.. | .. |
---|
76 | 76 | #define GC4653_MIRROR_BIT_MASK BIT(0) |
---|
77 | 77 | #define GC4653_FLIP_BIT_MASK BIT(1) |
---|
78 | 78 | |
---|
| 79 | +#define GC4653_FRAME_BUFFER_REG 0x031d |
---|
| 80 | +#define GC4653_FRAME_BUFFER_START 0x2d |
---|
| 81 | +#define GC4653_FRAME_BUFFER_END 0x28 |
---|
| 82 | + |
---|
79 | 83 | #define REG_NULL 0xFFFF |
---|
80 | 84 | |
---|
81 | 85 | #define GC4653_REG_VALUE_08BIT 1 |
---|
.. | .. |
---|
94 | 98 | }; |
---|
95 | 99 | |
---|
96 | 100 | #define GC4653_NUM_SUPPLIES ARRAY_SIZE(gc4653_supply_names) |
---|
97 | | - |
---|
98 | | -enum gc4653_max_pad { |
---|
99 | | - PAD0, /* link to isp */ |
---|
100 | | - PAD1, /* link to csi wr0 | hdr x2:L x3:M */ |
---|
101 | | - PAD2, /* link to csi wr1 | hdr x3:L */ |
---|
102 | | - PAD3, /* link to csi wr2 | hdr x2:M x3:S */ |
---|
103 | | - PAD_MAX, |
---|
104 | | -}; |
---|
105 | 101 | |
---|
106 | 102 | struct regval { |
---|
107 | 103 | u16 addr; |
---|
.. | .. |
---|
672 | 668 | struct gc4653 *gc4653 = to_gc4653(sd); |
---|
673 | 669 | const struct gc4653_mode *mode = gc4653->cur_mode; |
---|
674 | 670 | |
---|
675 | | - mutex_lock(&gc4653->mutex); |
---|
676 | 671 | fi->interval = mode->max_fps; |
---|
677 | | - mutex_unlock(&gc4653->mutex); |
---|
678 | 672 | |
---|
679 | 673 | return 0; |
---|
680 | 674 | } |
---|
681 | 675 | |
---|
682 | | -static int gc4653_g_mbus_config(struct v4l2_subdev *sd, |
---|
| 676 | +static int gc4653_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id, |
---|
683 | 677 | struct v4l2_mbus_config *config) |
---|
684 | 678 | { |
---|
685 | 679 | struct gc4653 *gc4653 = to_gc4653(sd); |
---|
.. | .. |
---|
691 | 685 | V4L2_MBUS_CSI2_CHANNEL_0 | |
---|
692 | 686 | V4L2_MBUS_CSI2_CONTINUOUS_CLOCK; |
---|
693 | 687 | |
---|
694 | | - config->type = V4L2_MBUS_CSI2; |
---|
| 688 | + config->type = V4L2_MBUS_CSI2_DPHY; |
---|
695 | 689 | config->flags = val; |
---|
696 | 690 | |
---|
697 | 691 | return 0; |
---|
.. | .. |
---|
707 | 701 | strscpy(inf->base.lens, gc4653->len_name, sizeof(inf->base.lens)); |
---|
708 | 702 | } |
---|
709 | 703 | |
---|
| 704 | +static int gc4653_get_channel_info(struct gc4653 *gc4653, struct rkmodule_channel_info *ch_info) |
---|
| 705 | +{ |
---|
| 706 | + if (ch_info->index < PAD0 || ch_info->index >= PAD_MAX) |
---|
| 707 | + return -EINVAL; |
---|
| 708 | + ch_info->vc = gc4653->cur_mode->vc[ch_info->index]; |
---|
| 709 | + ch_info->width = gc4653->cur_mode->width; |
---|
| 710 | + ch_info->height = gc4653->cur_mode->height; |
---|
| 711 | + ch_info->bus_fmt = gc4653->cur_mode->bus_fmt; |
---|
| 712 | + return 0; |
---|
| 713 | +} |
---|
| 714 | + |
---|
710 | 715 | static long gc4653_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) |
---|
711 | 716 | { |
---|
712 | 717 | struct gc4653 *gc4653 = to_gc4653(sd); |
---|
.. | .. |
---|
714 | 719 | u32 i, h, w; |
---|
715 | 720 | long ret = 0; |
---|
716 | 721 | u32 stream = 0; |
---|
| 722 | + struct rkmodule_channel_info *ch_info; |
---|
717 | 723 | |
---|
718 | 724 | switch (cmd) { |
---|
719 | 725 | case RKMODULE_GET_MODULE_INFO: |
---|
.. | .. |
---|
772 | 778 | ret = gc4653_write_reg(gc4653->client, GC4653_REG_CTRL_MODE, |
---|
773 | 779 | GC4653_REG_VALUE_08BIT, GC4653_MODE_SW_STANDBY); |
---|
774 | 780 | break; |
---|
| 781 | + case RKMODULE_GET_CHANNEL_INFO: |
---|
| 782 | + ch_info = (struct rkmodule_channel_info *)arg; |
---|
| 783 | + ret = gc4653_get_channel_info(gc4653, ch_info); |
---|
| 784 | + break; |
---|
775 | 785 | default: |
---|
776 | 786 | ret = -ENOIOCTLCMD; |
---|
777 | 787 | break; |
---|
.. | .. |
---|
791 | 801 | struct preisp_hdrae_exp_s *hdrae; |
---|
792 | 802 | long ret; |
---|
793 | 803 | u32 stream = 0; |
---|
| 804 | + struct rkmodule_channel_info *ch_info; |
---|
794 | 805 | |
---|
795 | 806 | switch (cmd) { |
---|
796 | 807 | case RKMODULE_GET_MODULE_INFO: |
---|
.. | .. |
---|
871 | 882 | ret = gc4653_ioctl(sd, cmd, &stream); |
---|
872 | 883 | else |
---|
873 | 884 | ret = -EFAULT; |
---|
| 885 | + break; |
---|
| 886 | + case RKMODULE_GET_CHANNEL_INFO: |
---|
| 887 | + ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL); |
---|
| 888 | + if (!ch_info) { |
---|
| 889 | + ret = -ENOMEM; |
---|
| 890 | + return ret; |
---|
| 891 | + } |
---|
| 892 | + |
---|
| 893 | + ret = gc4653_ioctl(sd, cmd, ch_info); |
---|
| 894 | + if (!ret) { |
---|
| 895 | + ret = copy_to_user(up, ch_info, sizeof(*ch_info)); |
---|
| 896 | + if (ret) |
---|
| 897 | + ret = -EFAULT; |
---|
| 898 | + } |
---|
| 899 | + kfree(ch_info); |
---|
874 | 900 | break; |
---|
875 | 901 | default: |
---|
876 | 902 | ret = -ENOIOCTLCMD; |
---|
.. | .. |
---|
1158 | 1184 | static const struct v4l2_subdev_video_ops gc4653_video_ops = { |
---|
1159 | 1185 | .s_stream = gc4653_s_stream, |
---|
1160 | 1186 | .g_frame_interval = gc4653_g_frame_interval, |
---|
1161 | | - .g_mbus_config = gc4653_g_mbus_config, |
---|
1162 | 1187 | }; |
---|
1163 | 1188 | |
---|
1164 | 1189 | static const struct v4l2_subdev_pad_ops gc4653_pad_ops = { |
---|
.. | .. |
---|
1167 | 1192 | .enum_frame_interval = gc4653_enum_frame_interval, |
---|
1168 | 1193 | .get_fmt = gc4653_get_fmt, |
---|
1169 | 1194 | .set_fmt = gc4653_set_fmt, |
---|
| 1195 | + .get_mbus_config = gc4653_g_mbus_config, |
---|
1170 | 1196 | }; |
---|
1171 | 1197 | |
---|
1172 | 1198 | static const struct v4l2_subdev_ops gc4653_subdev_ops = { |
---|
.. | .. |
---|
1232 | 1258 | val |= GC4653_MIRROR_BIT_MASK; |
---|
1233 | 1259 | else |
---|
1234 | 1260 | val &= ~GC4653_MIRROR_BIT_MASK; |
---|
| 1261 | + ret |= gc4653_write_reg(gc4653->client, GC4653_FRAME_BUFFER_REG, |
---|
| 1262 | + GC4653_REG_VALUE_08BIT, GC4653_FRAME_BUFFER_START); |
---|
1235 | 1263 | ret |= gc4653_write_reg(gc4653->client, GC4653_FLIP_MIRROR_REG, |
---|
1236 | 1264 | GC4653_REG_VALUE_08BIT, val); |
---|
| 1265 | + ret |= gc4653_write_reg(gc4653->client, GC4653_FRAME_BUFFER_REG, |
---|
| 1266 | + GC4653_REG_VALUE_08BIT, GC4653_FRAME_BUFFER_END); |
---|
1237 | 1267 | break; |
---|
1238 | 1268 | case V4L2_CID_VFLIP: |
---|
1239 | 1269 | ret = gc4653_read_reg(gc4653->client, GC4653_FLIP_MIRROR_REG, |
---|
.. | .. |
---|
1242 | 1272 | val |= GC4653_FLIP_BIT_MASK; |
---|
1243 | 1273 | else |
---|
1244 | 1274 | val &= ~GC4653_FLIP_BIT_MASK; |
---|
| 1275 | + ret |= gc4653_write_reg(gc4653->client, GC4653_FRAME_BUFFER_REG, |
---|
| 1276 | + GC4653_REG_VALUE_08BIT, GC4653_FRAME_BUFFER_START); |
---|
1245 | 1277 | ret |= gc4653_write_reg(gc4653->client, GC4653_FLIP_MIRROR_REG, |
---|
1246 | 1278 | GC4653_REG_VALUE_08BIT, val); |
---|
| 1279 | + ret |= gc4653_write_reg(gc4653->client, GC4653_FRAME_BUFFER_REG, |
---|
| 1280 | + GC4653_REG_VALUE_08BIT, GC4653_FRAME_BUFFER_END); |
---|
1247 | 1281 | break; |
---|
1248 | 1282 | default: |
---|
1249 | 1283 | dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n", |
---|