diff --git a/config/motorola,osprey.ini b/config/motorola,osprey.ini index 0e33a7f..3378d08 100644 --- a/config/motorola,osprey.ini +++ b/config/motorola,osprey.ini @@ -8,6 +8,6 @@ media-driver=qcom-camss width=4096 height=2304 rate=30 -fmt=RGGB8 +fmt=RGGB10P rotate=270 media-links=msm_csiphy0:1->msm_csid0:0,msm_csid0:1->msm_ispif0:0,msm_ispif0:1->msm_vfe0_rdi0:0 diff --git a/main.c b/main.c index f0152b3..5b5c8b1 100644 --- a/main.c +++ b/main.c @@ -42,6 +42,8 @@ struct mp_media_link { int target_port; unsigned int source_entity_id; unsigned int target_entity_id; + char source_fname[260]; + char target_fname[260]; int valid; }; @@ -473,6 +475,7 @@ init_sensor(char *fn, int width, int height, int mbus, int rate) g_printerr("Driver chose %dx%d fmt %d instead\n", fmt.format.width, fmt.format.height, fmt.format.code); + // Trigger continuous auto focus if the sensor supports it if (v4l2_has_control(fd, V4L2_CID_FOCUS_AUTO)) { @@ -501,6 +504,53 @@ init_sensor(char *fn, int width, int height, int mbus, int rate) current.fd = fd; } +int +find_dev_node(int maj, int min, char *fnbuf) +{ + DIR *d; + struct dirent *dir; + struct stat info; + d = opendir("/dev"); + while ((dir = readdir(d)) != NULL) { + sprintf(fnbuf, "/dev/%s", dir->d_name); + stat(fnbuf, &info); + if (!S_ISCHR(info.st_mode)) { + continue; + } + if (major(info.st_rdev) == maj && minor(info.st_rdev) == min) { + return 0; + } + } + return -1; +} + +static void +init_media_entity(char *fn, int width, int height, int mbus) +{ + int fd; + struct v4l2_subdev_format fmt = {}; + + fd = open(fn, O_RDWR); + + // Apply mode to v4l2 subdev + g_print("Setting node to %dx%d fmt %d\n", + width, height, mbus); + fmt.pad = 0; + fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; + fmt.format.code = mbus; + fmt.format.width = width; + fmt.format.height = height; + fmt.format.field = V4L2_FIELD_ANY; + + if (xioctl(fd, VIDIOC_SUBDEV_S_FMT, &fmt) == -1) { + errno_exit("VIDIOC_SUBDEV_S_FMT"); + } + if (fmt.format.width != width || fmt.format.height != height || fmt.format.code != mbus) + g_printerr("Driver chose %dx%d fmt %d instead\n", + fmt.format.width, fmt.format.height, + fmt.format.code); +} + static int init_device(int fd) { @@ -697,6 +747,7 @@ process_image(const int *p, int size) case V4L2_PIX_FMT_SGBRG8: case V4L2_PIX_FMT_SGRBG8: case V4L2_PIX_FMT_SRGGB8: + case V4L2_PIX_FMT_SRGGB10P: quick_debayer((const uint8_t *)p, pixels, current.fmt, current.width, current.height, skip, current.blacklevel); @@ -1094,6 +1145,9 @@ config_ini_handler(void *user, const char *section, const char *name, } else if (strcmp(value, "GBRG8") == 0) { cc->fmt = V4L2_PIX_FMT_SGBRG8; cc->mbus = MEDIA_BUS_FMT_SGBRG8_1X8; + } else if (strcmp(value, "RGGB10P") == 0) { + cc->fmt = V4L2_PIX_FMT_SRGGB10P; + cc->mbus = MEDIA_BUS_FMT_SRGGB10_1X10; } else if (strcmp(value, "UYVY") == 0) { cc->fmt = V4L2_PIX_FMT_UYVY; cc->mbus = MEDIA_BUS_FMT_UYVY8_2X8; @@ -1172,26 +1226,6 @@ config_ini_handler(void *user, const char *section, const char *name, return 1; } -int -find_dev_node(int maj, int min, char *fnbuf) -{ - DIR *d; - struct dirent *dir; - struct stat info; - d = opendir("/dev"); - while ((dir = readdir(d)) != NULL) { - sprintf(fnbuf, "/dev/%s", dir->d_name); - stat(fnbuf, &info); - if (!S_ISCHR(info.st_mode)) { - continue; - } - if (major(info.st_rdev) == maj && minor(info.st_rdev) == min) { - return 0; - } - } - return -1; -} - int setup_camera(int cid) { @@ -1226,6 +1260,8 @@ setup_camera(int cid) link.sink.entity = cameras[cid].interface_entity_id; link.sink.index = 0; + current = cameras[cid]; + if (xioctl(cameras[cid].media_fd, MEDIA_IOC_SETUP_LINK, &link) < 0) { g_printerr("[%s] Could not enable direct sensor->if link\n", cameras[cid].cfg_name); @@ -1258,9 +1294,10 @@ setup_camera(int cid) cameras[cid].media_links[i].target_port); } + init_media_entity(cameras[cid].media_links[i].source_fname, current.width, current.height, current.mbus); + init_media_entity(cameras[cid].media_links[i].target_fname, current.width, current.height, current.mbus); } } - current = cameras[cid]; // Find camera node init_sensor(current.dev_fname, current.width, current.height, current.mbus, current.rate); @@ -1326,10 +1363,14 @@ find_camera_found_media: if(strncmp(entity.name, cameras[cid].media_links[i].source_name, strlen(cameras[cid].media_links[i].source_name)) == 0) { cameras[cid].media_links[i].source_entity_id = entity.id; + find_dev_node(entity.dev.major, entity.dev.minor, cameras[cid].media_links[i].source_fname); + printf("[%s] isp: %s (%s)\n", cameras[cid].cfg_name, cameras[cid].media_links[i].source_fname, entity.name); } if(strncmp(entity.name, cameras[cid].media_links[i].target_name, strlen(cameras[cid].media_links[i].target_name)) == 0) { cameras[cid].media_links[i].target_entity_id = entity.id; + find_dev_node(entity.dev.major, entity.dev.minor, cameras[cid].media_links[i].target_fname); + printf("[%s] isp: %s (%s)\n", cameras[cid].cfg_name, cameras[cid].media_links[i].target_fname, entity.name); } } }