.. | .. |
---|
556 | 556 | } |
---|
557 | 557 | |
---|
558 | 558 | static int rk1608_msg_init_sensor(struct rk1608_state *pdata, |
---|
559 | | - struct msg_init *msg, int id) |
---|
| 559 | + struct msg_init *msg, int in_mipi, int out_mipi, |
---|
| 560 | + int id, int cam_id) |
---|
560 | 561 | { |
---|
561 | 562 | u32 idx = pdata->dphy[id]->fmt_inf_idx; |
---|
562 | 563 | |
---|
563 | 564 | msg->msg_head.size = sizeof(struct msg_init); |
---|
564 | 565 | msg->msg_head.type = id_msg_init_sensor_t; |
---|
565 | | - msg->msg_head.id.camera_id = id; |
---|
| 566 | + msg->msg_head.id.camera_id = cam_id; |
---|
566 | 567 | msg->msg_head.mux.sync = 1; |
---|
567 | | - msg->in_mipi_phy = pdata->dphy[id]->in_mipi; |
---|
568 | | - msg->out_mipi_phy = pdata->dphy[id]->out_mipi; |
---|
| 568 | + msg->in_mipi_phy = in_mipi; |
---|
| 569 | + msg->out_mipi_phy = out_mipi; |
---|
569 | 570 | msg->mipi_lane = pdata->dphy[id]->fmt_inf[idx].mipi_lane; |
---|
570 | 571 | msg->bayer = 0; |
---|
571 | 572 | memcpy(msg->sensor_name, pdata->dphy[id]->sensor_name, |
---|
.. | .. |
---|
573 | 574 | |
---|
574 | 575 | msg->i2c_slave_addr = pdata->dphy[id]->i2c_addr; |
---|
575 | 576 | msg->i2c_bus = pdata->dphy[id]->i2c_bus; |
---|
| 577 | + msg->sub_sensor_num = pdata->dphy[id]->sub_sensor_num; |
---|
576 | 578 | |
---|
577 | 579 | return rk1608_send_msg_to_dsp(pdata, &msg->msg_head); |
---|
578 | 580 | } |
---|
.. | .. |
---|
580 | 582 | static int rk1608_msg_init_dsp_time(struct rk1608_state *pdata, |
---|
581 | 583 | struct msg_init_dsp_time *msg, int id) |
---|
582 | 584 | { |
---|
583 | | - struct timeval tv; |
---|
| 585 | + u64 usecs64; |
---|
| 586 | + u32 mod; |
---|
584 | 587 | |
---|
585 | 588 | msg->msg_head.size = sizeof(struct msg_init_dsp_time); |
---|
586 | 589 | msg->msg_head.type = id_msg_sys_time_set_t; |
---|
587 | 590 | msg->msg_head.id.camera_id = id; |
---|
588 | 591 | msg->msg_head.mux.sync = 0; |
---|
589 | 592 | |
---|
590 | | - do_gettimeofday(&tv); |
---|
591 | | - msg->tv_sec = tv.tv_sec; |
---|
592 | | - msg->tv_usec = tv.tv_usec; |
---|
| 593 | + usecs64 = ktime_to_us(ktime_get()); |
---|
| 594 | + |
---|
| 595 | + mod = do_div(usecs64, USEC_PER_MSEC); |
---|
| 596 | + msg->tv_usec = mod; |
---|
| 597 | + msg->tv_sec = usecs64; |
---|
593 | 598 | |
---|
594 | 599 | return rk1608_send_msg_to_dsp(pdata, &msg->msg_head); |
---|
595 | 600 | } |
---|
596 | 601 | |
---|
597 | 602 | static int rk1608_msg_set_input_size(struct rk1608_state *pdata, |
---|
598 | | - struct msg_in_size *msg, int id) |
---|
| 603 | + struct msg_in_size *msg, int id, int cam_id) |
---|
599 | 604 | { |
---|
600 | 605 | u32 i; |
---|
601 | 606 | u32 msg_size = sizeof(struct msg); |
---|
.. | .. |
---|
617 | 622 | |
---|
618 | 623 | msg->msg_head.size = msg_size / sizeof(int); |
---|
619 | 624 | msg->msg_head.type = id_msg_set_input_size_t; |
---|
620 | | - msg->msg_head.id.camera_id = id; |
---|
| 625 | + msg->msg_head.id.camera_id = cam_id; |
---|
621 | 626 | msg->msg_head.mux.sync = 1; |
---|
622 | 627 | |
---|
623 | 628 | return rk1608_send_msg_to_dsp(pdata, &msg->msg_head); |
---|
624 | 629 | } |
---|
625 | 630 | |
---|
626 | 631 | static int rk1608_msg_set_output_size(struct rk1608_state *pdata, |
---|
627 | | - struct msg_set_output_size *msg, int id) |
---|
| 632 | + struct msg_set_output_size *msg, int id, int cam_id) |
---|
628 | 633 | { |
---|
629 | 634 | u32 i; |
---|
630 | 635 | u32 msg_size = sizeof(struct msg_out_size_head); |
---|
.. | .. |
---|
646 | 651 | |
---|
647 | 652 | msg->head.msg_head.size = msg_size / sizeof(int); |
---|
648 | 653 | msg->head.msg_head.type = id_msg_set_output_size_t; |
---|
649 | | - msg->head.msg_head.id.camera_id = id; |
---|
| 654 | + msg->head.msg_head.id.camera_id = cam_id; |
---|
650 | 655 | msg->head.msg_head.mux.sync = 1; |
---|
651 | 656 | msg->head.width = fmt_inf->hactive; |
---|
652 | 657 | msg->head.height = fmt_inf->vactive; |
---|
653 | 658 | msg->head.mipi_clk = 2 * pdata->dphy[id]->link_freqs; |
---|
654 | 659 | msg->head.line_length_pclk = fmt_inf->htotal; |
---|
655 | 660 | msg->head.frame_length_lines = fmt_inf->vtotal; |
---|
656 | | - msg->head.mipi_lane = fmt_inf->mipi_lane; |
---|
| 661 | + msg->head.mipi_lane = fmt_inf->mipi_lane_out; |
---|
657 | 662 | msg->head.flip = pdata->flip; |
---|
658 | 663 | |
---|
659 | 664 | return rk1608_send_msg_to_dsp(pdata, &msg->head.msg_head); |
---|
.. | .. |
---|
930 | 935 | return ret; |
---|
931 | 936 | } |
---|
932 | 937 | |
---|
| 938 | +static int rk1608_init_virtual_sub_sensor( |
---|
| 939 | + struct rk1608_state *pdata, int id, int index) |
---|
| 940 | +{ |
---|
| 941 | + struct msg *msg = NULL; |
---|
| 942 | + struct msg_init *msg_init = NULL; |
---|
| 943 | + struct msg_in_size *msg_in_size = NULL; |
---|
| 944 | + struct msg_set_output_size *msg_out_size = NULL; |
---|
| 945 | + int cam_id = pdata->dphy[id]->sub_sensor[index].id; |
---|
| 946 | + int in_mipi = pdata->dphy[id]->sub_sensor[index].in_mipi; |
---|
| 947 | + int out_mipi = pdata->dphy[id]->sub_sensor[index].out_mipi; |
---|
| 948 | + int ret = 0; |
---|
| 949 | + |
---|
| 950 | + msg = kzalloc(sizeof(*msg), GFP_KERNEL); |
---|
| 951 | + if (!msg) { |
---|
| 952 | + ret = -ENOMEM; |
---|
| 953 | + goto err; |
---|
| 954 | + } |
---|
| 955 | + msg_init = kzalloc(sizeof(*msg_init), GFP_KERNEL); |
---|
| 956 | + if (!msg_init) { |
---|
| 957 | + ret = -ENOMEM; |
---|
| 958 | + goto err; |
---|
| 959 | + } |
---|
| 960 | + |
---|
| 961 | + msg_in_size = kzalloc(sizeof(*msg_in_size), GFP_KERNEL); |
---|
| 962 | + if (!msg_in_size) { |
---|
| 963 | + ret = -ENOMEM; |
---|
| 964 | + goto err; |
---|
| 965 | + } |
---|
| 966 | + msg_out_size = kzalloc(sizeof(*msg_out_size), GFP_KERNEL); |
---|
| 967 | + if (!msg_out_size) { |
---|
| 968 | + ret = -ENOMEM; |
---|
| 969 | + goto err; |
---|
| 970 | + } |
---|
| 971 | + |
---|
| 972 | + ret = rk1608_msg_init_sensor(pdata, msg_init, in_mipi, out_mipi, id, cam_id); |
---|
| 973 | + ret |= rk1608_msg_set_input_size(pdata, msg_in_size, id, cam_id); |
---|
| 974 | + ret |= rk1608_msg_set_output_size(pdata, msg_out_size, id, cam_id); |
---|
| 975 | + ret |= rk1608_msg_set_stream_in_on(pdata, msg, cam_id); |
---|
| 976 | + |
---|
| 977 | +err: |
---|
| 978 | + kfree(msg_init); |
---|
| 979 | + kfree(msg_in_size); |
---|
| 980 | + kfree(msg_out_size); |
---|
| 981 | + kfree(msg); |
---|
| 982 | + |
---|
| 983 | + return ret; |
---|
| 984 | +} |
---|
| 985 | + |
---|
933 | 986 | static int rk1608_init_sensor(struct rk1608_state *pdata, int id) |
---|
934 | 987 | { |
---|
935 | 988 | struct msg *msg = NULL; |
---|
.. | .. |
---|
937 | 990 | struct msg_in_size *msg_in_size = NULL; |
---|
938 | 991 | struct msg_set_output_size *msg_out_size = NULL; |
---|
939 | 992 | struct msg_init_dsp_time *msg_init_time = NULL; |
---|
| 993 | + int in_mipi = pdata->dphy[id]->in_mipi; |
---|
| 994 | + int out_mipi = pdata->dphy[id]->out_mipi; |
---|
| 995 | + int cam_id = id; |
---|
940 | 996 | int ret = 0; |
---|
941 | 997 | |
---|
942 | 998 | if (!pdata->sensor[id]) { |
---|
.. | .. |
---|
972 | 1028 | goto err; |
---|
973 | 1029 | } |
---|
974 | 1030 | |
---|
975 | | - ret = rk1608_msg_init_sensor(pdata, msg_init, id); |
---|
| 1031 | + |
---|
| 1032 | + ret = rk1608_msg_init_sensor(pdata, msg_init, in_mipi, out_mipi, id, cam_id); |
---|
976 | 1033 | ret |= rk1608_msg_init_dsp_time(pdata, msg_init_time, id); |
---|
977 | | - ret |= rk1608_msg_set_input_size(pdata, msg_in_size, id); |
---|
978 | | - ret |= rk1608_msg_set_output_size(pdata, msg_out_size, id); |
---|
979 | | - ret |= rk1608_msg_set_stream_in_on(pdata, msg, id); |
---|
980 | | - ret |= rk1608_msg_set_stream_out_on(pdata, msg, id); |
---|
| 1034 | + ret |= rk1608_msg_set_input_size(pdata, msg_in_size, id, cam_id); |
---|
| 1035 | + ret |= rk1608_msg_set_output_size(pdata, msg_out_size, id, cam_id); |
---|
| 1036 | + ret |= rk1608_msg_set_stream_in_on(pdata, msg, cam_id); |
---|
| 1037 | + ret |= rk1608_msg_set_stream_out_on(pdata, msg, cam_id); |
---|
981 | 1038 | |
---|
982 | 1039 | err: |
---|
983 | 1040 | kfree(msg_init); |
---|
.. | .. |
---|
1029 | 1086 | { |
---|
1030 | 1087 | struct spi_device *spi = pdata->spi; |
---|
1031 | 1088 | int ret = 0; |
---|
| 1089 | + |
---|
| 1090 | + if (pdata->pwren_gpio) |
---|
| 1091 | + gpiod_direction_output(pdata->pwren_gpio, 1); |
---|
1032 | 1092 | |
---|
1033 | 1093 | if (!IS_ERR(pdata->mclk)) { |
---|
1034 | 1094 | ret = clk_set_rate(pdata->mclk, RK1608_MCLK_RATE); |
---|
.. | .. |
---|
1093 | 1153 | if (pdata->reset_gpio) |
---|
1094 | 1154 | gpiod_direction_output(pdata->reset_gpio, 0); |
---|
1095 | 1155 | rk1608_cs_set_value(pdata, 0); |
---|
| 1156 | + |
---|
| 1157 | + if (pdata->pwren_gpio) |
---|
| 1158 | + gpiod_direction_output(pdata->pwren_gpio, 0); |
---|
1096 | 1159 | |
---|
1097 | 1160 | if (!IS_ERR(pdata->mclk)) |
---|
1098 | 1161 | clk_disable_unprepare(pdata->mclk); |
---|
.. | .. |
---|
1166 | 1229 | static int rk1608_stream_on(struct rk1608_state *pdata) |
---|
1167 | 1230 | { |
---|
1168 | 1231 | int id = 0, cnt = 0, ret = 0; |
---|
| 1232 | + int sub_sensor_num = 0, index = 0; |
---|
1169 | 1233 | |
---|
1170 | 1234 | mutex_lock(&pdata->lock); |
---|
1171 | 1235 | id = pdata->sd.grp_id; |
---|
1172 | 1236 | pdata->sensor_cnt = 0; |
---|
1173 | 1237 | pdata->set_exp_cnt = 1; |
---|
| 1238 | + |
---|
| 1239 | + sub_sensor_num = pdata->dphy[id]->sub_sensor_num; |
---|
| 1240 | + for (index = 0; index < sub_sensor_num; index++) { |
---|
| 1241 | + ret = rk1608_init_virtual_sub_sensor(pdata, id, index); |
---|
| 1242 | + if (ret) { |
---|
| 1243 | + dev_err(pdata->dev, "Init rk1608[%d] sub[%d] is failed!", |
---|
| 1244 | + id, |
---|
| 1245 | + index); |
---|
| 1246 | + mutex_unlock(&pdata->lock); |
---|
| 1247 | + return ret; |
---|
| 1248 | + } |
---|
| 1249 | + } |
---|
| 1250 | + |
---|
1174 | 1251 | ret = rk1608_init_sensor(pdata, id); |
---|
1175 | 1252 | if (ret) { |
---|
1176 | 1253 | dev_err(pdata->dev, "Init rk1608[%d] is failed!", |
---|
.. | .. |
---|
1212 | 1289 | |
---|
1213 | 1290 | static int rk1608_stream_off(struct rk1608_state *pdata) |
---|
1214 | 1291 | { |
---|
| 1292 | + u32 sub_sensor_num = 0, index = 0, sub_id = 0; |
---|
| 1293 | + |
---|
1215 | 1294 | mutex_lock(&pdata->sensor_lock); |
---|
1216 | 1295 | pdata->sensor_cnt = 0; |
---|
1217 | 1296 | mutex_unlock(&pdata->sensor_lock); |
---|
| 1297 | + |
---|
| 1298 | + sub_sensor_num = pdata->dphy[pdata->sd.grp_id]->sub_sensor_num; |
---|
| 1299 | + for (index = 0; index < sub_sensor_num; index++) { |
---|
| 1300 | + sub_id = pdata->dphy[pdata->sd.grp_id]->sub_sensor[index].id; |
---|
| 1301 | + rk1608_deinit(pdata, sub_id); |
---|
| 1302 | + } |
---|
| 1303 | + |
---|
1218 | 1304 | rk1608_deinit(pdata, pdata->sd.grp_id); |
---|
1219 | 1305 | |
---|
1220 | 1306 | return 0; |
---|
| 1307 | +} |
---|
| 1308 | + |
---|
| 1309 | +static int rk1608_set_quick_stream(struct rk1608_state *pdata, void *args) |
---|
| 1310 | +{ |
---|
| 1311 | + u32 stream = *(u32 *)args; |
---|
| 1312 | + |
---|
| 1313 | + if (stream) |
---|
| 1314 | + return rk1608_stream_on(pdata); |
---|
| 1315 | + else |
---|
| 1316 | + return rk1608_stream_off(pdata); |
---|
1221 | 1317 | } |
---|
1222 | 1318 | |
---|
1223 | 1319 | static int rk1608_s_stream(struct v4l2_subdev *sd, int enable) |
---|
.. | .. |
---|
1338 | 1434 | break; |
---|
1339 | 1435 | case PREISP_DISP_SET_LED_ON_OFF: |
---|
1340 | 1436 | rk1608_disp_set_led_on_off(pdata, arg); |
---|
| 1437 | + break; |
---|
| 1438 | + case RKMODULE_SET_QUICK_STREAM: |
---|
| 1439 | + rk1608_set_quick_stream(pdata, arg); |
---|
1341 | 1440 | break; |
---|
1342 | 1441 | default: |
---|
1343 | 1442 | return -ENOTTY; |
---|
.. | .. |
---|
1880 | 1979 | unsigned int file_size = 0; |
---|
1881 | 1980 | unsigned int write_size = 0; |
---|
1882 | 1981 | char *file_data = NULL; |
---|
1883 | | - struct kstat *stat; |
---|
1884 | 1982 | struct msg_xfile *xfile; |
---|
1885 | 1983 | |
---|
1886 | 1984 | char *ref_data_path = REF_DATA_PATH; |
---|
.. | .. |
---|
1899 | 1997 | return -EFAULT; |
---|
1900 | 1998 | } |
---|
1901 | 1999 | |
---|
1902 | | - stat = kmalloc(sizeof(*stat), GFP_KERNEL); |
---|
1903 | | - if (!stat) { |
---|
1904 | | - ret = -ENOMEM; |
---|
1905 | | - goto err; |
---|
1906 | | - } |
---|
1907 | | - |
---|
1908 | | - vfs_stat(file_path, stat); |
---|
1909 | | - |
---|
1910 | | - file_size = stat->size; |
---|
1911 | | - file_size = (file_size+0x3)&(~0x3); |
---|
1912 | | - |
---|
1913 | 2000 | dev_info(pdata->dev, "start import %s to addr:0x%x size:%d\n", |
---|
1914 | | - file_path, xfile->addr, file_size); |
---|
| 2001 | + file_path, xfile->addr, xfile->data_size); |
---|
1915 | 2002 | |
---|
1916 | | - file_data = vmalloc(file_size); |
---|
| 2003 | + file_data = vmalloc(xfile->data_size); |
---|
1917 | 2004 | if (!file_data) { |
---|
1918 | 2005 | ret = -ENOMEM; |
---|
1919 | 2006 | goto err; |
---|
1920 | 2007 | } |
---|
1921 | 2008 | |
---|
1922 | | - ret = kernel_read(fp, file_data, file_size, &pos); |
---|
1923 | | - if (ret <= 0) |
---|
| 2009 | + file_size = kernel_read(fp, file_data, xfile->data_size, &pos); |
---|
| 2010 | + if (file_size <= 0) { |
---|
1924 | 2011 | dev_err(pdata->dev, "%s: read error: ret=%d\n", |
---|
1925 | 2012 | __func__, ret); |
---|
| 2013 | + goto err; |
---|
| 2014 | + } |
---|
1926 | 2015 | |
---|
1927 | 2016 | write_size = (file_size <= xfile->data_size)?file_size:xfile->data_size; |
---|
1928 | 2017 | if (file_size != xfile->data_size) |
---|
.. | .. |
---|
1946 | 2035 | xfile->path, xfile->addr, file_size); |
---|
1947 | 2036 | |
---|
1948 | 2037 | err: |
---|
1949 | | - kfree(stat); |
---|
1950 | 2038 | if (file_data) |
---|
1951 | 2039 | vfree(file_data); |
---|
1952 | 2040 | if (fp) |
---|
.. | .. |
---|
2098 | 2186 | goto err; |
---|
2099 | 2187 | } |
---|
2100 | 2188 | |
---|
2101 | | - if (head->item[i].size > 128) { |
---|
| 2189 | + if (head->item[i].size > sizeof(calibdata_->calib_sn_code)) { |
---|
2102 | 2190 | dev_err(pdata->dev, "%s: %s size:%d error!\n", |
---|
2103 | 2191 | __func__, head->item[i].name, head->item[i].size); |
---|
2104 | 2192 | goto err; |
---|
.. | .. |
---|
2115 | 2203 | |
---|
2116 | 2204 | pos = head->item[i].offset; |
---|
2117 | 2205 | |
---|
2118 | | - ret = kernel_read(fp, (char *)&calibdata_->calib_sn_code, head->item[i].size, &pos); |
---|
| 2206 | + ret = kernel_read(fp, (char *)calibdata_->calib_sn_code, head->item[i].size, &pos); |
---|
2119 | 2207 | if (ret <= 0) { |
---|
2120 | 2208 | dev_err(pdata->dev, "%s: read error: ret=%d\n", __func__, ret); |
---|
2121 | 2209 | goto err; |
---|
.. | .. |
---|
2299 | 2387 | #define PREISP_DCROP_CALIB_RATIO 192 |
---|
2300 | 2388 | #define PREISP_DCROP_CALIB_XOFFSET 196 |
---|
2301 | 2389 | #define PREISP_DCROP_CALIB_YOFFSET 198 |
---|
2302 | | -static int rk1608_get_dcrop_cfg(struct v4l2_rect *crop_in, |
---|
| 2390 | +int rk1608_get_dcrop_cfg(struct v4l2_rect *crop_in, |
---|
2303 | 2391 | struct v4l2_rect *crop_out) |
---|
2304 | 2392 | { |
---|
2305 | 2393 | struct file *fp; |
---|
.. | .. |
---|
2706 | 2794 | MODULE_AUTHOR("Rockchip Camera/ISP team"); |
---|
2707 | 2795 | MODULE_DESCRIPTION("A DSP driver for rk1608 chip"); |
---|
2708 | 2796 | MODULE_LICENSE("GPL v2"); |
---|
| 2797 | +MODULE_IMPORT_NS(VFS_internal_I_am_really_a_filesystem_and_am_NOT_a_driver); |
---|