TDA4VM相机调试常用code

dmesg

dmesg | grep Async

Linux诊断机器故障工具—dmesg命令

如何在 Linux 上使用 dmesg 命令_linux dmesg_Linux猿的博客-CSDN博客

记录到内核环形缓冲区的每个消息都有一个附加的级别。 级别表示信息的重要性。 包含的级别有:

  • emerg : 系统无法使用;
  • alert : 必须立即采取措施;
  • crit : 严重的情况;
  • err : 错误;
  • warn : 警告;
  • notice : 正常但是重要的情况;
  • info : 消息;
  • debug : 调试信息;

通过使用 -l(level)参数并将级别的名称作为命令行参数传递,可以提取与特定级别匹配的消息。 如果查看“informational”级别的消息,请使用如下命令:

$ sudo dmesg -l info

列出的所有消息都是"info"消息。 它们不包含错误或警告,仅包含有用的通知。

MAX96712

max96712.c - drivers/staging/media/max96712/max96712.c - Linux source code (v5.17.15) - Bootlin

// SPDX-License-Identifier: GPL-2.0
/*
 * Maxim MAX9286 Quad GMSL2 Deserializer Driver
 *
 * Copyright (C) 2021 Renesas Electronics Corporation
 * Copyright (C) 2021 Niklas Söderlund
 */

#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/of_graph.h>
#include <linux/regmap.h>

#include <media/v4l2-ctrls.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-subdev.h>

#define MAX96712_ID 0x20

#define MAX96712_DPLL_FREQ 1000

enum max96712_pattern {
	MAX96712_PATTERN_CHECKERBOARD = 0,
	MAX96712_PATTERN_GRADIENT,
};

struct max96712_priv {
	struct i2c_client *client;
	struct regmap *regmap;
	struct gpio_desc *gpiod_pwdn;

	struct v4l2_fwnode_bus_mipi_csi2 mipi;

	struct v4l2_subdev sd;
	struct v4l2_ctrl_handler ctrl_handler;
	struct media_pad pads[1];

	enum max96712_pattern pattern;
};

static int max96712_read(struct max96712_priv *priv, int reg)
{
	int ret, val;

	ret = regmap_read(priv->regmap, reg, &val);
	if (ret) {
		dev_err(&priv->client->dev, "read 0x%04x failed\n", reg);
		return ret;
	}

	return val;
}

static int max96712_write(struct max96712_priv *priv, unsigned int reg, u8 val)
{
	int ret;

	ret = regmap_write(priv->regmap, reg, val);
	if (ret)
		dev_err(&priv->client->dev, "write 0x%04x failed\n", reg);

	return ret;
}

static int max96712_update_bits(struct max96712_priv *priv, unsigned int reg,
				u8 mask, u8 val)
{
	int ret;

	ret = regmap_update_bits(priv->regmap, reg, mask, val);
	if (ret)
		dev_err(&priv->client->dev, "update 0x%04x failed\n", reg);

	return ret;
}

static int max96712_write_bulk(struct max96712_priv *priv, unsigned int reg,
			       const void *val, size_t val_count)
{
	int ret;

	ret = regmap_bulk_write(priv->regmap, reg, val, val_count);
	if (ret)
		dev_err(&priv->client->dev, "bulk write 0x%04x failed\n", reg);

	return ret;
}

static int max96712_write_bulk_value(struct max96712_priv *priv,
				     unsigned int reg, unsigned int val,
				     size_t val_count)
{
	unsigned int i;
	u8 values[4];

	for (i = 1; i <= val_count; i++)
		values[i - 1] = (val >> ((val_count - i) * 8)) & 0xff;

	return max96712_write_bulk(priv, reg, &values, val_count);
}

static void max96712_reset(struct max96712_priv *priv)
{
	max96712_update_bits(priv, 0x13, 0x40, 0x40);
	msleep(20);
}

static void max96712_mipi_enable(struct max96712_priv *priv, bool enable)
{
	if (enable) {
		max96712_update_bits(priv, 0x40b, 0x02, 0x02);
		max96712_update_bits(priv, 0x8a0, 0x80, 0x80);
	} else {
		max96712_update_bits(priv, 0x8a0, 0x80, 0x00);
		max96712_update_bits(priv, 0x40b, 0x02, 0x00);
	}
}

static void max96712_mipi_configure(struct max96712_priv *priv)
{
	unsigned int i;
	u8 phy5 = 0;

	max96712_mipi_enable(priv, false);

	/* Select 2x4 mode. */
	max96712_write(priv, 0x8a0, 0x04);

	/* Configure a 4-lane DPHY using PHY0 and PHY1. */
	/* TODO: Add support for 2-lane and 1-lane configurations. */
	/* TODO: Add support CPHY mode. */
	max96712_write(priv, 0x94a, 0xc0);

	/* Configure lane mapping for PHY0 and PHY1. */
	/* TODO: Add support for lane swapping. */
	max96712_write(priv, 0x8a3, 0xe4);

	/* Configure lane polarity for PHY0 and PHY1. */
	for (i = 0; i < priv->mipi.num_data_lanes + 1; i++)
		if (priv->mipi.lane_polarities[i])
			phy5 |= BIT(i == 0 ? 5 : i < 3 ? i - 1 : i);
	max96712_write(priv, 0x8a5, phy5);

	/* Set link frequency for PHY0 and PHY1. */
	max96712_update_bits(priv, 0x415, 0x3f,
			     ((MAX96712_DPLL_FREQ / 100) & 0x1f) | BIT(5));
	max96712_update_bits(priv, 0x418, 0x3f,
			     ((MAX96712_DPLL_FREQ / 100) & 0x1f) | BIT(5));

	/* Enable PHY0 and PHY1 */
	max96712_update_bits(priv, 0x8a2, 0xf0, 0x30);
}

static void max96712_pattern_enable(struct max96712_priv *priv, bool enable)
{
	const u32 h_active = 1920;
	const u32 h_fp = 88;
	const u32 h_sw = 44;
	const u32 h_bp = 148;
	const u32 h_tot = h_active + h_fp + h_sw + h_bp;

	const u32 v_active = 1080;
	const u32 v_fp = 4;
	const u32 v_sw = 5;
	const u32 v_bp = 36;
	const u32 v_tot = v_active + v_fp + v_sw + v_bp;

	if (!enable) {
		max96712_write(priv, 0x1051, 0x00);
		return;
	}

	/* PCLK 75MHz. */
	max96712_write(priv, 0x0009, 0x01);

	/* Configure Video Timing Generator for 1920x1080 @ 30 fps. */
	max96712_write_bulk_value(priv, 0x1052, 0, 3);
	max96712_write_bulk_value(priv, 0x1055, v_sw * h_tot, 3);
	max96712_write_bulk_value(priv, 0x1058,
				  (v_active + v_fp + + v_bp) * h_tot, 3);
	max96712_write_bulk_value(priv, 0x105b, 0, 3);
	max96712_write_bulk_value(priv, 0x105e, h_sw, 2);
	max96712_write_bulk_value(priv, 0x1060, h_active + h_fp + h_bp, 2);
	max96712_write_bulk_value(priv, 0x1062, v_tot, 2);
	max96712_write_bulk_value(priv, 0x1064,
				  h_tot * (v_sw + v_bp) + (h_sw + h_bp), 3);
	max96712_write_bulk_value(priv, 0x1067, h_active, 2);
	max96712_write_bulk_value(priv, 0x1069, h_fp + h_sw + h_bp, 2);
	max96712_write_bulk_value(priv, 0x106b, v_active, 2);

	/* Generate VS, HS and DE in free-running mode. */
	max96712_write(priv, 0x1050, 0xfb);

	/* Configure Video Pattern Generator. */
	if (priv->pattern == MAX96712_PATTERN_CHECKERBOARD) {
		/* Set checkerboard pattern size. */
		max96712_write(priv, 0x1074, 0x3c);
		max96712_write(priv, 0x1075, 0x3c);
		max96712_write(priv, 0x1076, 0x3c);

		/* Set checkerboard pattern colors. */
		max96712_write_bulk_value(priv, 0x106e, 0xfecc00, 3);
		max96712_write_bulk_value(priv, 0x1071, 0x006aa7, 3);

		/* Generate checkerboard pattern. */
		max96712_write(priv, 0x1051, 0x10);
	} else {
		/* Set gradient increment. */
		max96712_write(priv, 0x106d, 0x10);

		/* Generate gradient pattern. */
		max96712_write(priv, 0x1051, 0x20);
	}
}

static int max96712_s_stream(struct v4l2_subdev *sd, int enable)
{
	struct max96712_priv *priv = v4l2_get_subdevdata(sd);

	if (enable) {
		max96712_pattern_enable(priv, true);
		max96712_mipi_enable(priv, true);
	} else {
		max96712_mipi_enable(priv, false);
		max96712_pattern_enable(priv, false);
	}

	return 0;
}

static const struct v4l2_subdev_video_ops max96712_video_ops = {
	.s_stream = max96712_s_stream,
};

static int max96712_get_pad_format(struct v4l2_subdev *sd,
				   struct v4l2_subdev_state *sd_state,
				   struct v4l2_subdev_format *format)
{
	format->format.width = 1920;
	format->format.height = 1080;
	format->format.code = MEDIA_BUS_FMT_RGB888_1X24;
	format->format.field = V4L2_FIELD_NONE;

	return 0;
}

static const struct v4l2_subdev_pad_ops max96712_pad_ops = {
	.get_fmt = max96712_get_pad_format,
	.set_fmt = max96712_get_pad_format,
};

static const struct v4l2_subdev_ops max96712_subdev_ops = {
	.video = &max96712_video_ops,
	.pad = &max96712_pad_ops,
};

static const char * const max96712_test_pattern[] = {
	"Checkerboard",
	"Gradient",
};

static int max96712_s_ctrl(struct v4l2_ctrl *ctrl)
{
	struct max96712_priv *priv =
		container_of(ctrl->handler, struct max96712_priv, ctrl_handler);

	switch (ctrl->id) {
	case V4L2_CID_TEST_PATTERN:
		priv->pattern = ctrl->val ?
			MAX96712_PATTERN_GRADIENT :
			MAX96712_PATTERN_CHECKERBOARD;
		break;
	}
	return 0;
}

static const struct v4l2_ctrl_ops max96712_ctrl_ops = {
	.s_ctrl = max96712_s_ctrl,
};

static int max96712_v4l2_register(struct max96712_priv *priv)
{
	long pixel_rate;
	int ret;

	v4l2_i2c_subdev_init(&priv->sd, priv->client, &max96712_subdev_ops);
	priv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
	priv->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;

	v4l2_ctrl_handler_init(&priv->ctrl_handler, 2);

	/*
	 * TODO: Once V4L2_CID_LINK_FREQ is changed from a menu control to an
	 * INT64 control it should be used here instead of V4L2_CID_PIXEL_RATE.
	 */
	pixel_rate = MAX96712_DPLL_FREQ / priv->mipi.num_data_lanes * 1000000;
	v4l2_ctrl_new_std(&priv->ctrl_handler, NULL, V4L2_CID_PIXEL_RATE,
			  pixel_rate, pixel_rate, 1, pixel_rate);

	v4l2_ctrl_new_std_menu_items(&priv->ctrl_handler, &max96712_ctrl_ops,
				     V4L2_CID_TEST_PATTERN,
				     ARRAY_SIZE(max96712_test_pattern) - 1,
				     0, 0, max96712_test_pattern);

	priv->sd.ctrl_handler = &priv->ctrl_handler;
	ret = priv->ctrl_handler.error;
	if (ret)
		goto error;

	priv->pads[0].flags = MEDIA_PAD_FL_SOURCE;
	ret = media_entity_pads_init(&priv->sd.entity, 1, priv->pads);
	if (ret)
		goto error;

	v4l2_set_subdevdata(&priv->sd, priv);

	ret = v4l2_async_register_subdev(&priv->sd);
	if (ret < 0) {
		dev_err(&priv->client->dev, "Unable to register subdevice\n");
		goto error;
	}

	return 0;
error:
	v4l2_ctrl_handler_free(&priv->ctrl_handler);

	return ret;
}

static int max96712_parse_dt(struct max96712_priv *priv)
{
	struct fwnode_handle *ep;
	struct v4l2_fwnode_endpoint v4l2_ep = {
		.bus_type = V4L2_MBUS_CSI2_DPHY
	};
	int ret;

	ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(&priv->client->dev), 4,
					     0, 0);
	if (!ep) {
		dev_err(&priv->client->dev, "Not connected to subdevice\n");
		return -EINVAL;
	}

	ret = v4l2_fwnode_endpoint_parse(ep, &v4l2_ep);
	fwnode_handle_put(ep);
	if (ret) {
		dev_err(&priv->client->dev, "Could not parse v4l2 endpoint\n");
		return -EINVAL;
	}

	if (v4l2_ep.bus.mipi_csi2.num_data_lanes != 4) {
		dev_err(&priv->client->dev, "Only 4 data lanes supported\n");
		return -EINVAL;
	}

	priv->mipi = v4l2_ep.bus.mipi_csi2;

	return 0;
}

static const struct regmap_config max96712_i2c_regmap = {
	.reg_bits = 16,
	.val_bits = 8,
	.max_register = 0x1f00,
};

static int max96712_probe(struct i2c_client *client)
{
	struct max96712_priv *priv;
	int ret;

	priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	priv->client = client;
	i2c_set_clientdata(client, priv);

	priv->regmap = devm_regmap_init_i2c(client, &max96712_i2c_regmap);
	if (IS_ERR(priv->regmap))
		return PTR_ERR(priv->regmap);

	priv->gpiod_pwdn = devm_gpiod_get_optional(&client->dev, "enable",
						   GPIOD_OUT_HIGH);
	if (IS_ERR(priv->gpiod_pwdn))
		return PTR_ERR(priv->gpiod_pwdn);

	gpiod_set_consumer_name(priv->gpiod_pwdn, "max96712-pwdn");
	gpiod_set_value_cansleep(priv->gpiod_pwdn, 1);

	if (priv->gpiod_pwdn)
		usleep_range(4000, 5000);

	if (max96712_read(priv, 0x4a) != MAX96712_ID)
		return -ENODEV;

	max96712_reset(priv);

	ret = max96712_parse_dt(priv);
	if (ret)
		return ret;

	max96712_mipi_configure(priv);

	return max96712_v4l2_register(priv);
}

static int max96712_remove(struct i2c_client *client)
{
	struct max96712_priv *priv = i2c_get_clientdata(client);

	v4l2_async_unregister_subdev(&priv->sd);

	gpiod_set_value_cansleep(priv->gpiod_pwdn, 0);

	return 0;
}

static const struct of_device_id max96712_of_table[] = {
	{ .compatible = "maxim,max96712" },
	{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, max96712_of_table);

static struct i2c_driver max96712_i2c_driver = {
	.driver	= {
		.name = "max96712",
		.of_match_table	= of_match_ptr(max96712_of_table),
	},
	.probe_new = max96712_probe,
	.remove = max96712_remove,
};

module_i2c_driver(max96712_i2c_driver);

MODULE_DESCRIPTION("Maxim MAX96712 Quad GMSL2 Deserializer Driver");
MODULE_AUTHOR("Niklas Söderlund <niklas.soderlund@ragnatech.se>");
MODULE_LICENSE("GPL");

 

capture

./capture /dev/video0 1920 1080 1

convert -size 1920x1080 -depth 16 uyvy:frame.raw frame.png # convert to png via imagemagick

 

/*
 *  V4L2 video capture example
 *
 *  This program can be used and distributed without restrictions.
 *
 *      This program is provided with the V4L2 API
 * see http://linuxtv.org/docs.php for more information
 */

#include <byteswap.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <assert.h>
#include <fcntl.h>              /* low-level i/o */
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/ioctl.h>

#include <linux/videodev2.h>

#define CLEAR(x) memset(&(x), 0, sizeof(x))

struct buffer {
        void   *start;
        size_t  length;
};

static void errno_exit(const char *s)
{
        fprintf(stderr, "%s error %d, %s\n", s, errno, strerror(errno));
        exit(EXIT_FAILURE);
}

static int xioctl(int fh, int request, void *arg)
{
        int r;

        do {
                r = ioctl(fh, request, arg);
        } while (-1 == r && EINTR == errno);

        return r;
}

/* 16bit/pixel interleaved YUV */
static void process_image(const void *_p, struct v4l2_pix_format *fmt)
{
        const uint8_t *p = _p;
        int8_t u;
        uint8_t y1;
        int8_t v;
        uint8_t y2;
        int r, g, b, c, d ,e;
        int red, i, x, y;
        int size = fmt->sizeimage;

        printf("Processing Frame: %dx%d %c%c%c%c\n",
                fmt->width, fmt->height,
                (fmt->pixelformat >> 0) & 0xff,
                (fmt->pixelformat >> 8) & 0xff,
                (fmt->pixelformat >> 16) & 0xff,
                (fmt->pixelformat >> 24) & 0xff);

        red = 0;
        for (i = 0; i < size; i += 4) {
                u = p[i+0];
                y1 = p[i+1];
                v = p[i+2];
                y2 = p[i+3];

                u -= 128;
                v -= 128;

                r = y1 + v + (v>>2) + (v>>3) + (v>>5);
                g = y1 - ((u>>2) + (u>>4) + (u>>5))
                       - ((v>>1) + (v>>3) + (v>>4) + (v>>5));
                b = y1 + u + (u>>1) + (u>>2) + (u>>6);
                if (r > 100 && g < 60 && b < 60) red++;

                r = y2 + v + (v>>2) + (v>>3) + (v>>5);
                g = y2 - ((u>>2) + (u>>4) + (u>>5))
                       - ((v>>1) + (v>>3) + (v>>4) + (v>>5));
                b = y2 + u + (u>>1) + (u>>2) + (u>>6);
                if (r > 100 && g < 60 && b < 60) red++;

                /* describe pixels on first line every 250 pixels
                 * (colorbars)
                 */
                x = (i>>1) % fmt->width;
                y = (i>>1) / fmt->height;
                if (y == 0 && !(x % 250)) {
                        printf("[%4d,%4d] YUYV:0x%02x%02x%02x%02x ",
                                        x,y,y1,(uint8_t)u,y2,(uint8_t)v);
                        printf("RGB:0x%02x%02x%02x\n", r,g,b);
                }
        }
        printf("red pixel count=%d\n", red);
}

static void save_frame(const char *path, const void *p, int size)
{
        int fd, rz;

        fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0755);
        if (fd < 0)
                perror("open");
        else {
                rz = write(fd, p, size);
                printf("Wrote %d of %d bytes to %s\n", rz, size, path);
                close(fd);
        }
}

int main(int argc, char **argv)
{
        static char *dev_name;
        int width, height;
        static int fd = -1;
        struct stat st;
        struct buffer *buffers;
        static unsigned int n_buffers;
        enum v4l2_buf_type type;
        struct v4l2_capability cap;
        struct v4l2_format fmt;
        struct v4l2_requestbuffers req;
        struct v4l2_streamparm parm;
        struct v4l2_input input;
        v4l2_std_id std_id;
        struct v4l2_buffer buf;
        unsigned int count;
        unsigned int i;
        char filename[32];

        /* parse args */
        if (argc < 5) {
                fprintf(stderr, "usage: %s <device> <width> <height> <count>\n",
                        argv[0]);
                exit(1);
        }
        dev_name = argv[1];
        width = atoi(argv[2]);
        height = atoi(argv[3]);
        count = atoi(argv[4]);

        /* open device */
        fd = open(dev_name, O_RDWR | O_NONBLOCK, 0);
        if (-1 == fd) {
                fprintf(stderr, "Cannot open '%s': %d, %s\n",
                                dev_name, errno, strerror(errno));
                exit(EXIT_FAILURE);
        }

        /* get standard (wait for it to be locked onto a signal) */
        if (-1 == xioctl(fd, VIDIOC_G_STD, &std_id))
                perror("VIDIOC_G_STD");
        for (i = 0; std_id == V4L2_STD_ALL && i < 10; i++) {
                usleep(100000);
                xioctl(fd, VIDIOC_G_STD, &std_id);
        }
        /* set the standard to the detected standard (this is critical for autodetect) */
        if (std_id != V4L2_STD_UNKNOWN) {
                if (-1 == xioctl(fd, VIDIOC_S_STD, &std_id))
                        perror("VIDIOC_S_STD");
                if (std_id & V4L2_STD_NTSC)
                        printf("found NTSC TV decoder\n");
                if (std_id & V4L2_STD_SECAM)
                        printf("found SECAM TV decoder\n");
                if (std_id & V4L2_STD_PAL)
                        printf("found PAL TV decoder\n");
        }

        /* ensure device has video capture capability */
        if (-1 == xioctl(fd, VIDIOC_QUERYCAP, &cap)) {
                if (EINVAL == errno) {
                        fprintf(stderr, "%s is no V4L2 device\n",
                                        dev_name);
                        exit(EXIT_FAILURE);
                } else {
                        errno_exit("VIDIOC_QUERYCAP");
                }
        }
        if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
                fprintf(stderr, "%s is no video capture device\n",
                                dev_name);
                exit(EXIT_FAILURE);
        }
        if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
                fprintf(stderr, "%s does not support streaming i/o\n",
                                dev_name);
                exit(EXIT_FAILURE);
        }

        /* set video input */
        CLEAR(input);
        input.index = 1; /* IMX6 v4l2 driver: input1 is CSI<->MEM */
        if (-1 == xioctl(fd, VIDIOC_S_INPUT, &input))
                perror("VIDIOC_S_INPUT");

        /* set framerate */
        CLEAR(parm);
        parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        if (-1 == xioctl(fd, VIDIOC_S_PARM, &parm))
                perror("VIDIOC_S_PARM");

        /* get framerate */
        CLEAR(parm);
        parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        if (-1 == xioctl(fd, VIDIOC_G_PARM, &parm))
                perror("VIDIOC_G_PARM");

        /* set format */
        CLEAR(fmt);
        fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        fmt.fmt.pix.width       = width;
        fmt.fmt.pix.height      = height;
        fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
        fmt.fmt.pix.field       = V4L2_FIELD_ANY;
        if (-1 == xioctl(fd, VIDIOC_S_FMT, &fmt))
                errno_exit("VIDIOC_S_FMT");

        /* get and display format */
        CLEAR(fmt);
        fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        if (-1 == xioctl(fd, VIDIOC_G_FMT, &fmt))
                errno_exit("VIDIOC_G_FMT");
        printf("%s: %dx%d %c%c%c%c %2.2ffps\n", dev_name,
                fmt.fmt.pix.width, fmt.fmt.pix.height,
                (fmt.fmt.pix.pixelformat >> 0) & 0xff,
                (fmt.fmt.pix.pixelformat >> 8) & 0xff,
                (fmt.fmt.pix.pixelformat >> 16) & 0xff,
                (fmt.fmt.pix.pixelformat >> 24) & 0xff,
                (float)parm.parm.capture.timeperframe.denominator /
                (float)parm.parm.capture.timeperframe.numerator
                );

        /* request buffers */
        CLEAR(req);
        req.count = 4;
        req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        req.memory = V4L2_MEMORY_MMAP;
        if (-1 == xioctl(fd, VIDIOC_REQBUFS, &req)) {
                if (EINVAL == errno) {
                        fprintf(stderr, "%s does not support "
                                 "memory mapping\n", dev_name);
                        exit(EXIT_FAILURE);
                } else {
                        errno_exit("VIDIOC_REQBUFS");
                }
        }
        if (req.count < 2) {
                fprintf(stderr, "Insufficient buffer memory on %s\n",
                         dev_name);
                exit(EXIT_FAILURE);
        }

        /* allocate buffers */
        buffers = calloc(req.count, sizeof(*buffers));
        if (!buffers) {
                fprintf(stderr, "Out of memory\n");
                exit(EXIT_FAILURE);
        }

        /* mmap buffers */
        for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {
                struct v4l2_buffer buf;

                CLEAR(buf);

                buf.type        = V4L2_BUF_TYPE_VIDEO_CAPTURE;
                buf.memory      = V4L2_MEMORY_MMAP;
                buf.index       = n_buffers;

                if (-1 == xioctl(fd, VIDIOC_QUERYBUF, &buf))
                        errno_exit("VIDIOC_QUERYBUF");

                buffers[n_buffers].length = buf.length;
                buffers[n_buffers].start =
                        mmap(NULL /* start anywhere */,
                              buf.length,
                              PROT_READ | PROT_WRITE /* required */,
                              MAP_SHARED /* recommended */,
                              fd, buf.m.offset);

                if (MAP_FAILED == buffers[n_buffers].start)
                        errno_exit("mmap");
        }

        /* queue buffers */
        for (i = 0; i < n_buffers; ++i) {
                struct v4l2_buffer buf;

                CLEAR(buf);
                buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
                buf.memory = V4L2_MEMORY_MMAP;
                buf.index = i;

                if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))
                        errno_exit("VIDIOC_QBUF");
        }

        /* start capture */
        type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        if (-1 == xioctl(fd, VIDIOC_STREAMON, &type))
                errno_exit("VIDIOC_STREAMON");

        /* capture frame(s) (we throw away first incomplete frame ) */
        for (i = 0; i < count + 1; i++) {
                for (;;) {
                        fd_set fds;
                        struct timeval tv;
                        int r;

                        FD_ZERO(&fds);
                        FD_SET(fd, &fds);

                        /* Timeout. */
                        tv.tv_sec = 2;
                        tv.tv_usec = 0;

                        r = select(fd + 1, &fds, NULL, NULL, &tv);
                        if (-1 == r) {
                                if (EINTR == errno)
                                        continue;
                                errno_exit("select");
                        }
                        if (0 == r) {
                                fprintf(stderr, "select timeout\n");
                                exit(EXIT_FAILURE);
                        }

                        /* dequeue captured buffer */
                        CLEAR(buf);
                        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
                        buf.memory = V4L2_MEMORY_MMAP;
                        if (-1 == xioctl(fd, VIDIOC_DQBUF, &buf)) {
                                if (errno == EAGAIN)
                                        continue;
                                errno_exit("VIDIOC_DQBUF");
                        }
                        assert(buf.index < n_buffers);

                        /* skip first image as it may not be sync'd */
                        if (i > 0) {
                                process_image(buffers[buf.index].start,
                                        &fmt.fmt.pix);
                                sprintf(filename, "frame%d.raw", i);
                                save_frame(filename,
                                        buffers[buf.index].start,
                                        buf.bytesused);
                        }

                        /* queue buffer */
                        if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))
                                errno_exit("VIDIOC_QBUF");

                        break;
                }
        }

        /* stop capture */
        type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        if (-1 == xioctl(fd, VIDIOC_STREAMOFF, &type))
                errno_exit("VIDIOC_STREAMOFF");

        /* unmap and free buffers */
        for (i = 0; i < n_buffers; ++i)
                if (-1 == munmap(buffers[i].start, buffers[i].length))
                        errno_exit("munmap");
        free(buffers);

        /* close device */
        if (-1 == close(fd))
                errno_exit("close");

        fprintf(stderr, "\n");
        return 0;
}

 

max9296+max9295+regester

 

echo "start config 9296"

i2ctransfer -f -y 9 w3@0x48 0x03 0x13 0x00
echo "start config 9295"

i2ctransfer -f -y 9 w3@0x40 0x02 0xbe 0x10

sleep 0.5
i2ctransfer -f -y 9 w3@0x40 0x03 0x18 0x5e

i2ctransfer -f -y 9 w3@0x40 0x02 0xd3 0x00
sleep 0.5
i2ctransfer -f -y 9 w3@0x40 0x02 0xd3 0x10
i2ctransfer -f -y 9 w3@0x40 0x02 0xd6 0x00
sleep 0.5
i2ctransfer -f -y 9 w3@0x40 0x02 0xd6 0x10
echo "start config 9296"

i2ctransfer -f -y 9 w3@0x48 0x00 0x52 0x01

i2ctransfer -f -y 9 w3@0x48 0x00 0x51 0x02

i2ctransfer -f -y 9 w3@0x48 0x03 0x20 0x2c 

i2ctransfer -f -y 9 w3@0x48 0x03 0x13 0x02

echo "end config"

 

v4l2-ctl -d /dev/video2 -V

v4l2-ctl --list-formats -d /dev/video2

yavta -c -Fcapture -s 1920x1080 -f UYVY /dev/video2

 

 

	max9296_write(priv, 0x048b, 0xff);
	max9296_write(priv, 0x048c, 0xff);
	max9296_write(priv, 0x048d, 0x1e);
	max9296_write(priv, 0x048e, 0x1e);
	max9296_write(priv, 0x048f, 0x00);
	max9296_write(priv, 0x0490, 0x00);
	max9296_write(priv, 0x0491, 0x01);
	max9296_write(priv, 0x0492, 0x01);
	max9296_write(priv, 0x0493, 0x02);
	max9296_write(priv, 0x0494, 0x02);
	max9296_write(priv, 0x0495, 0x03);
	max9296_write(priv, 0x0496, 0x03);
	max9296_write(priv, 0x0497, 0x04);
	max9296_write(priv, 0x0498, 0x04);
	max9296_write(priv, 0x0499, 0x05);
	max9296_write(priv, 0x049a, 0x05);
	max9296_write(priv, 0x049b, 0x06);
	max9296_write(priv, 0x049c, 0x06);
	max9296_write(priv, 0x049d, 0x07);
	max9296_write(priv, 0x049e, 0x07);
	max9296_write(priv, 0x049f, 0x08);
	max9296_write(priv, 0x04a0, 0x08);
	max9296_write(priv, 0x04a1, 0x09);
	max9296_write(priv, 0x04a2, 0x09);
	max9296_write(priv, 0x04a3, 0x0a);
	max9296_write(priv, 0x04a4, 0x0a);
	max9296_write(priv, 0x04a5, 0x0b);
	max9296_write(priv, 0x04a6, 0x0b);
	max9296_write(priv, 0x04a7, 0x0c);
	max9296_write(priv, 0x04a8, 0x0c);
	max9296_write(priv, 0x04a9, 0x0d);
	max9296_write(priv, 0x04aa, 0x0d);
	max9296_write(priv, 0x04ab, 0x0e);
	max9296_write(priv, 0x04ac, 0x0e);
	max9296_write(priv, 0x04ad, 0xaa);
	max9296_write(priv, 0x04ae, 0xaa);
	max9296_write(priv, 0x04af, 0xaa);
	max9296_write(priv, 0x04b0, 0xaa);

 

 

 

 

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

踏马潜行

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值