Martijn Braam пре 1 година
родитељ
комит
9137d56ea6
4 измењених фајлова са 46 додато и 0 уклоњено
  1. 2 0
      config/purism,librem5.conf
  2. 2 0
      include/libmegapixels.h
  3. 9 0
      src/parse.c
  4. 33 0
      src/pipeline.c

+ 2 - 0
config/purism,librem5.conf

@@ -17,6 +17,7 @@ Rear: {
             # All the links on this platform are immutable
             Pipeline: (
                 {Type: "Mode", Entity: "s5k3l6xx"},
+                {Type: "Rate", Entity: "s5k3l6xx"},
                 {Type: "Mode", Entity: "imx8mq-mipi-csi2"},
                 {Type: "Mode", Entity: "csi"},
             );
@@ -29,6 +30,7 @@ Rear: {
             Rotate: 270;
             Pipeline: (
                 {Type: "Mode", Entity: "s5k3l6xx"},
+                {Type: "Rate", Entity: "s5k3l6xx"},
                 {Type: "Mode", Entity: "imx8mq-mipi-csi2"},
                 {Type: "Mode", Entity: "csi"},
             );

+ 2 - 0
include/libmegapixels.h

@@ -13,6 +13,7 @@ libmegapixels_find_config(char *configfile);
 #define LIBMEGAPIXELS_CMD_LINK 1
 #define LIBMEGAPIXELS_CMD_MODE 2
 #define LIBMEGAPIXELS_CMD_CROP 3
+#define LIBMEGAPIXELS_CMD_INTERVAL 4
 
 #define LIBMEGAPIXELS_CFA_NONE 0
 #define LIBMEGAPIXELS_CFA_BGGR 1
@@ -31,6 +32,7 @@ struct _lmp_cmd {
 		int top;
 		int left;
 		int format;
+		int rate;
 
 		uint32_t entity_from_id;
 		int pad_from_id;

+ 9 - 0
src/parse.c

@@ -331,6 +331,15 @@ load_camera(libmegapixels_devconfig *config, config_t *cfg, const char *name)
 				} else {
 					cur->format = last_format;
 				}
+			} else if (strcmp(type, "Rate") == 0) {
+				camera->modes[n]->cmds[m]->type = LIBMEGAPIXELS_CMD_INTERVAL;
+				if (!config_setting_lookup_string(cmd, "Entity", &cur->entity_from)) {
+					fprintf(stderr, "Missing entity\n");
+					break;
+				}
+				if (!config_setting_lookup_int(cmd, "Rate", &cur->rate)) {
+					cur->rate = mm->rate;
+				}
 			} else if (strcmp(type, "Crop") == 0) {
 				camera->modes[n]->cmds[m]->type = LIBMEGAPIXELS_CMD_CROP;
 				if (!config_setting_lookup_string(cmd, "Entity", &cur->entity_from)) {

+ 33 - 0
src/pipeline.c

@@ -212,6 +212,7 @@ libmegapixels_select_mode(libmegapixels_camera *camera, libmegapixels_mode *mode
 		libmegapixels_cmd *cmd = mode->cmds[i];
 		struct v4l2_subdev_format subdev_fmt = {};
 		struct v4l2_subdev_crop subdev_crop = {};
+		struct v4l2_subdev_frame_interval subdev_ival = {};
 		int found = 0;
 		libmegapixels_subdev *sd;
 
@@ -258,6 +259,38 @@ libmegapixels_select_mode(libmegapixels_camera *camera, libmegapixels_mode *mode
 					log_error("Could not set mode on %s:%d: %s\n", cmd->entity_from, cmd->pad_from, strerror(errno));
 				}
 				break;
+			case LIBMEGAPIXELS_CMD_INTERVAL:
+				subdev_ival.pad = cmd->pad_from;
+				struct v4l2_fract ival;
+				ival.numerator = 1;
+				ival.denominator = cmd->rate;
+				subdev_ival.interval = ival;
+				log_debug("  Rate %s:%d [%d]\n", cmd->entity_from, cmd->pad_from, cmd->rate);
+
+				found = 0;
+				for (int h = 0; h < camera->num_handles; h++) {
+					if (camera->handles[h]->entity_id == cmd->entity_from_id) {
+						sd = camera->handles[h];
+						found++;
+					}
+				}
+				if (found != 1) {
+					log_error("Could not find handle for entity\n");
+					break;
+				}
+
+				if (sd->fd == 0) {
+					sd->fd = open(sd->path, O_RDWR);
+					if (sd->fd < 0) {
+						log_error("Could not open %s\n", sd->path);
+						break;
+					}
+				}
+
+				if (xioctl(sd->fd, VIDIOC_SUBDEV_S_FRAME_INTERVAL, &subdev_ival) == -1) {
+					log_error("Could not set rate on %s:%d: %s\n", cmd->entity_from, cmd->pad_from, strerror(errno));
+				}
+				break;
 			case LIBMEGAPIXELS_CMD_CROP:
 				subdev_crop.pad = cmd->pad_from;
 				subdev_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE;