| .. | .. |
|---|
| 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); |
|---|