diff options
Diffstat (limited to 'v4l2-apps')
-rw-r--r-- | v4l2-apps/test/pixfmt-test.c | 320 | ||||
-rw-r--r-- | v4l2-apps/util/Makefile | 14 | ||||
-rw-r--r-- | v4l2-apps/util/bttv-dbg.h | 97 | ||||
-rw-r--r-- | v4l2-apps/util/em28xx-dbg.h | 84 | ||||
-rw-r--r-- | v4l2-apps/util/saa7134-dbg.h | 141 | ||||
-rw-r--r-- | v4l2-apps/util/v4l-board-dbg.c | 335 | ||||
-rw-r--r-- | v4l2-apps/util/v4l-board-dbg.h | 24 |
7 files changed, 936 insertions, 79 deletions
diff --git a/v4l2-apps/test/pixfmt-test.c b/v4l2-apps/test/pixfmt-test.c index c8047e842..100d031d1 100644 --- a/v4l2-apps/test/pixfmt-test.c +++ b/v4l2-apps/test/pixfmt-test.c @@ -1,7 +1,7 @@ /* V4L2 pixfmt test - Copyright (C) 2007 Michael H. Schimek <mschimek@gmx.at> + Copyright (C) 2007, 2008 Michael H. Schimek <mschimek@gmx.at> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -100,14 +100,23 @@ typedef enum { /* Bayer formats. */ - BGGR, /* bbbbbbbb gggggggg */ + BGGR8, /* bbbbbbbb gggggggg */ /* gggggggg rrrrrrrr */ - GBRG, /* gggggggg bbbbbbbb */ + GBRG8, /* gggggggg bbbbbbbb */ /* rrrrrrrr gggggggg */ - RGGB, /* rrrrrrrr gggggggg */ + RGGB8, /* rrrrrrrr gggggggg */ /* gggggggg bbbbbbbb */ - GRBG, /* gggggggg rrrrrrrr */ + GRBG8, /* gggggggg rrrrrrrr */ /* bbbbbbbb gggggggg */ + + BGGR16, /* b7...b0 b15...b8 g7...g0 g15...g8 */ + /* g7...g0 g15...g8 r7...r0 r15...r8 */ + GBRG16, /* g7...g0 g15...g8 b7...b0 b15...b8 */ + /* r7...r0 r15...r8 g7...g0 g15...g8 */ + RGGB16, /* r7...r0 r15...r8 g7...g0 g15...g8 */ + /* g7...g0 g15...g8 b7...b0 b15...b8 */ + GRBG16, /* g7...g0 g15...g8 r7...r0 r15...r8 */ + /* b7...b0 b15...b8 g7...g0 g15...g8 */ } pixfmt; /* A pixfmt set would be nicer, but I doubt all @@ -219,7 +228,7 @@ typedef struct { #define PF_RGB24 PF_RGB16 #define PF_RGB32 PF_RGB16 -#define PF_BAYER(pf, pfxrb, vpf) \ +#define PF_BAYER(pf, pfxrb, bpp, vpf) \ [pf] = { \ .name = # pf, \ .v4l2_fourcc_name = (0 == vpf) ? NULL : # vpf, \ @@ -230,8 +239,8 @@ typedef struct { .pixfmt_class = BAYER, \ .v4l2_fourcc = vpf, \ .byte_order = LE, \ - .bits_per_pixel = 8, \ - .color_depth = 24 /* sort of */ \ + .bits_per_pixel = bpp, \ + .color_depth = bpp * 3 /* sort of */ \ } static const pixel_format @@ -298,10 +307,15 @@ pixel_formats [] = { PF_RGB8 (RGB332, BGR233, 0, 0xE0, 0x1C, 0x03, 0), - PF_BAYER (BGGR, RGGB, V4L2_PIX_FMT_SBGGR8), - PF_BAYER (RGGB, BGGR, 0), - PF_BAYER (GBRG, GRBG, 0), - PF_BAYER (GRBG, GBRG, 0), + PF_BAYER (BGGR8, RGGB8, 8, V4L2_PIX_FMT_SBGGR8), + PF_BAYER (RGGB8, BGGR8, 8, 0), + PF_BAYER (GBRG8, GRBG8, 8, 0), + PF_BAYER (GRBG8, GBRG8, 8, 0), + + PF_BAYER (BGGR16, RGGB16, 16, V4L2_PIX_FMT_SBGGR16), + PF_BAYER (RGGB16, BGGR16, 16, 0), + PF_BAYER (GBRG16, GRBG16, 16, 0), + PF_BAYER (GRBG16, GBRG16, 16, 0), }; static const pixel_format * @@ -364,7 +378,7 @@ static const char * my_name; static const char * dev_name = "/dev/video"; -static int fd; +static int dev_fd; static v4l2_std_id std_id; static io_methods io_method; static struct v4l2_format fmt; @@ -406,13 +420,16 @@ write_rgb_pixel (uint8_t * dst, const pixel_format * dst_pf, unsigned int b, unsigned int g, - unsigned int r) + unsigned int r, + unsigned int depth) { unsigned int dst_pixel; + unsigned int shl; - dst_pixel = ((b << 24) >> dst_pf->shr[0]) & dst_pf->mask[0]; - dst_pixel |= ((g << 24) >> dst_pf->shr[1]) & dst_pf->mask[1]; - dst_pixel |= ((r << 24) >> dst_pf->shr[2]) & dst_pf->mask[2]; + shl = 32 - depth; + dst_pixel = ((b << shl) >> dst_pf->shr[0]) & dst_pf->mask[0]; + dst_pixel |= ((g << shl) >> dst_pf->shr[1]) & dst_pf->mask[1]; + dst_pixel |= ((r << shl) >> dst_pf->shr[2]) & dst_pf->mask[2]; switch (dst_pf->byte_order * 256 + dst_pf->bits_per_pixel) { case LE * 256 + 32: @@ -443,7 +460,7 @@ write_rgb_pixel (uint8_t * dst, } static void -convert_bayer_image (uint8_t * dst, +convert_bayer8_image (uint8_t * dst, const pixel_format * dst_pf, unsigned long dst_bpl, const uint8_t * src, @@ -466,19 +483,19 @@ convert_bayer_image (uint8_t * dst, assert ((long) dst_padding >= 0); switch (src_pf->pixfmt) { - case BGGR: + case BGGR8: tile = 0; break; - case GBRG: + case GBRG8: tile = 1; break; - case RGGB: + case RGGB8: tile = 2; break; - case GRBG: + case GRBG8: tile = 3; break; @@ -490,7 +507,7 @@ convert_bayer_image (uint8_t * dst, for (y = 0; y < height; ++y) { const uint8_t *srcm; const uint8_t *srcp; - int x; + unsigned int x; srcm = srcp = src - src_bpl; @@ -518,7 +535,8 @@ convert_bayer_image (uint8_t * dst, /* r */ (srcm[xm] + srcm[xp] + srcp[xm] + - srcp[xp] + 2) >> 2); + srcp[xp] + 2) >> 2, + /* depth */ 8); break; case 1: /* GB @@ -528,7 +546,8 @@ convert_bayer_image (uint8_t * dst, src[xp] + 1) >> 1, /* g */ src[x], /* r */ (srcm[x] + - srcp[x] + 1) >> 1); + srcp[x] + 1) >> 1, + /* depth */ 8); break; case 2: /* GR @@ -538,7 +557,8 @@ convert_bayer_image (uint8_t * dst, srcp[x] + 1) >> 1, /* g */ src[x], /* r */ (src[xm] + - src[xp] + 1) >> 1); + src[xp] + 1) >> 1, + /* depth */ 8); break; case 3: /* RG @@ -552,7 +572,8 @@ convert_bayer_image (uint8_t * dst, src[xp] + srcm[x] + srcp[x] + 2) >> 2, - /* r */ src[x]); + /* r */ src[x], + /* depth */ 8); break; default: @@ -573,6 +594,143 @@ convert_bayer_image (uint8_t * dst, } static void +convert_bayer16_image (uint8_t * dst, + const pixel_format * dst_pf, + unsigned long dst_bpl, + const uint16_t * src, + const pixel_format * src_pf, + unsigned long src_bpl, + unsigned int width, + unsigned int height) +{ + unsigned long dst_padding; + unsigned int tile; + unsigned int y; + + assert (PACKED_RGB == dst_pf->pixfmt_class); + assert (BAYER == src_pf->pixfmt_class); + + assert (width >= 2 && 0 == (width & 1)); + assert (height >= 2 && 0 == (height & 1)); + + dst_padding = dst_bpl - width * (dst_pf->bits_per_pixel >> 3); + assert ((long) dst_padding >= 0); + + switch (src_pf->pixfmt) { + case BGGR16: + tile = 0; + break; + + case GBRG16: + tile = 1; + break; + + case RGGB16: + tile = 2; + break; + + case GRBG16: + tile = 3; + break; + + default: + assert (0); + break; + } + + for (y = 0; y < height; ++y) { + const uint16_t *srcm; + const uint16_t *srcp; + unsigned int x; + + srcm = srcp = (const uint16_t *) + ((char *) src - src_bpl); + + if (0 == y) + srcm = (const uint16_t *) + ((char *) srcm + src_bpl * 2); + + if (y != height - 1) + srcp = (const uint16_t *) + ((char *) srcp + src_bpl * 2); + + for (x = 0; x < width; ++x) { + int xm, xp; + + xm = (((0 == x) - 1) | 1) + x; + xp = (((x != width - 1) - 1) | 1) + x; + + switch (tile) { + case 0: /* BG + GR */ + write_rgb_pixel (dst, dst_pf, + /* b */ src[x], + /* g */ (src[xm] + + src[xp] + + srcm[x] + + srcp[x] + 2) >> 2, + /* r */ (srcm[xm] + + srcm[xp] + + srcp[xm] + + srcp[xp] + 2) >> 2, + /* depth */ 10); + break; + + case 1: /* GB + RG */ + write_rgb_pixel (dst, dst_pf, + /* b */ (src[xm] + + src[xp] + 1) >> 1, + /* g */ src[x], + /* r */ (srcm[x] + + srcp[x] + 1) >> 1, + /* depth */ 10); + break; + + case 2: /* GR + BG */ + write_rgb_pixel (dst, dst_pf, + /* b */ (srcm[x] + + srcp[x] + 1) >> 1, + /* g */ src[x], + /* r */ (src[xm] + + src[xp] + 1) >> 1, + /* depth */ 10); + break; + + case 3: /* RG + GB */ + write_rgb_pixel (dst, dst_pf, + /* b */ (srcm[xm] + + srcm[xp] + + srcp[xm] + + srcp[xp] + 2) >> 2, + /* g */ (src[xm] + + src[xp] + + srcm[x] + + srcp[x] + 2) >> 2, + /* r */ src[x], + /* depth */ 10); + break; + + default: + assert (0); + break; + } + + tile ^= 1; + + dst += dst_pf->bits_per_pixel >> 3; + } + + tile ^= 2; + + dst += dst_padding; + src = (const uint16_t *)((char *) src + src_bpl); + } +} + +static void convert_packed_rgb_pixel (uint8_t * dst, const pixel_format * dst_pf, const uint8_t * src, @@ -669,9 +827,16 @@ convert_rgb_image (uint8_t * dst, assert (PACKED_RGB == dst_pf->pixfmt_class); if (BAYER == src_pf->pixfmt_class) { - convert_bayer_image (dst, dst_pf, dst_bpl, - src, src_pf, src_bpl, - width, height); + if (8 == src_pf->bits_per_pixel) { + convert_bayer8_image (dst, dst_pf, dst_bpl, + src, src_pf, src_bpl, + width, height); + } else { + convert_bayer16_image (dst, dst_pf, dst_bpl, + (const uint16_t *) src, + src_pf, src_bpl, + width, height); + } return; } @@ -751,13 +916,13 @@ create_ximage (const pixel_format ** pf, unsigned int width, unsigned int height) { - XImage *ximage; + XImage *xi; unsigned int image_size; unsigned int i; assert (NULL != display); - ximage = XCreateImage (display, + xi = XCreateImage (display, DefaultVisual (display, screen), DefaultDepth (display, screen), ZPixmap, @@ -767,24 +932,24 @@ create_ximage (const pixel_format ** pf, height, /* bitmap_pad (n/a) */ 8, /* bytes_per_line: auto */ 0); - if (NULL == ximage) { + if (NULL == xi) { error_exit ("Cannot allocate XImage.\n"); } for (i = 0; i < N_ELEMENTS (pixel_formats); ++i) { if (PACKED_RGB != pixel_formats[i].pixfmt_class) continue; - if ((LSBFirst == ximage->byte_order) + if ((LSBFirst == xi->byte_order) != (LE == pixel_formats[i].byte_order)) continue; - if (ximage->bits_per_pixel + if (xi->bits_per_pixel != pixel_formats[i].bits_per_pixel) continue; - if (ximage->blue_mask != pixel_formats[i].mask[0]) + if (xi->blue_mask != pixel_formats[i].mask[0]) continue; - if (ximage->green_mask != pixel_formats[i].mask[1]) + if (xi->green_mask != pixel_formats[i].mask[1]) continue; - if (ximage->red_mask != pixel_formats[i].mask[2]) + if (xi->red_mask != pixel_formats[i].mask[2]) continue; break; } @@ -792,27 +957,27 @@ create_ximage (const pixel_format ** pf, if (i >= N_ELEMENTS (pixel_formats)) { error_exit ("Unknown XImage pixel format " "(bpp=%u %s b=0x%08x g=0x%08x r=0x%08x).\n", - ximage->bits_per_pixel, - (LSBFirst == ximage->byte_order) ? + xi->bits_per_pixel, + (LSBFirst == xi->byte_order) ? "LSBFirst" : "MSBFirst", - ximage->blue_mask, - ximage->green_mask, - ximage->red_mask); + xi->blue_mask, + xi->green_mask, + xi->red_mask); } if (NULL != pf) *pf = pixel_formats + i; - image_size = (ximage->bytes_per_line * ximage->height); + image_size = (xi->bytes_per_line * xi->height); - ximage->data = malloc (image_size); - if (NULL == ximage->data) { + xi->data = malloc (image_size); + if (NULL == xi->data) { error_exit ("Cannot allocate XImage data (%u bytes).\n", image_size); exit (EXIT_FAILURE); } - return ximage; + return xi; } static void @@ -901,10 +1066,10 @@ display_image (const uint8_t * image, font = XQueryFont (display, XGContextFromGC (gc)); text_height = font->max_bounds.ascent + font->max_bounds.descent; - if (image_width > ximage->width - || image_width != wa.width - || image_height > ximage->height - || image_height + text_height != wa.height) { + if (image_width > (unsigned int) ximage->width + || image_width != (unsigned int) wa.width + || image_height > (unsigned int) ximage->height + || image_height + text_height != (unsigned int) wa.height) { resize_window (image_width, image_height, /* text_width */ image_width, @@ -978,6 +1143,10 @@ display_image (const uint8_t * image, /* y */ image_height + font->max_bounds.ascent, &xti, /* n_items */ 1); + + free (xti.chars); + + XFreeFontInfo (/* names */ NULL, font, 1); } static void @@ -1062,7 +1231,8 @@ read_and_display_frame (const pixel_format * conv_pf) switch (io_method) { case IO_METHOD_READ: - if (-1 == read (fd, buffers[0].start, buffers[0].length)) { + if (-1 == read (dev_fd, buffers[0].start, + buffers[0].length)) { switch (errno) { case EAGAIN: return false; @@ -1087,7 +1257,7 @@ read_and_display_frame (const pixel_format * conv_pf) buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; - if (-1 == xioctl (fd, VIDIOC_DQBUF, &buf)) { + if (-1 == xioctl (dev_fd, VIDIOC_DQBUF, &buf)) { switch (errno) { case EAGAIN: return false; @@ -1111,7 +1281,7 @@ read_and_display_frame (const pixel_format * conv_pf) fmt.fmt.pix.width, fmt.fmt.pix.height); - if (-1 == xioctl (fd, VIDIOC_QBUF, &buf)) + if (-1 == xioctl (dev_fd, VIDIOC_QBUF, &buf)) errno_exit ("VIDIOC_QBUF"); break; @@ -1129,13 +1299,12 @@ wait_for_next_frame (void) int r; FD_ZERO (&fds); - FD_SET (fd, &fds); + FD_SET (dev_fd, &fds); timeout.tv_sec = 2; timeout.tv_usec = 0; - r = select (fd + 1, &fds, NULL, NULL, &timeout); - + r = select (dev_fd + 1, &fds, NULL, NULL, &timeout); if (-1 == r) { if (EINTR == errno) continue; @@ -1166,7 +1335,7 @@ flush_capture_queue (void) buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; - if (-1 == xioctl (fd, VIDIOC_DQBUF, &buf)) { + if (-1 == xioctl (dev_fd, VIDIOC_DQBUF, &buf)) { switch (errno) { case EAGAIN: return; @@ -1176,7 +1345,7 @@ flush_capture_queue (void) } } - if (-1 == xioctl (fd, VIDIOC_QBUF, &buf)) + if (-1 == xioctl (dev_fd, VIDIOC_QBUF, &buf)) errno_exit ("VIDIOC_QBUF"); break; @@ -1232,7 +1401,7 @@ stop_capturing (void) case IO_METHOD_MMAP: type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - if (-1 == xioctl (fd, VIDIOC_STREAMOFF, &type)) + if (-1 == xioctl (dev_fd, VIDIOC_STREAMOFF, &type)) errno_exit ("VIDIOC_STREAMOFF"); break; @@ -1260,13 +1429,13 @@ start_capturing (void) buf.memory = V4L2_MEMORY_MMAP; buf.index = i; - if (-1 == xioctl (fd, VIDIOC_QBUF, &buf)) + if (-1 == xioctl (dev_fd, VIDIOC_QBUF, &buf)) errno_exit ("VIDIOC_QBUF"); } type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - if (-1 == xioctl (fd, VIDIOC_STREAMON, &type)) + if (-1 == xioctl (dev_fd, VIDIOC_STREAMON, &type)) errno_exit ("VIDIOC_STREAMON"); break; @@ -1336,7 +1505,7 @@ init_mmap_io (void) req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; req.memory = V4L2_MEMORY_MMAP; - if (-1 == xioctl (fd, VIDIOC_REQBUFS, &req)) { + if (-1 == xioctl (dev_fd, VIDIOC_REQBUFS, &req)) { if (EINVAL == errno) { error_exit ("%s does not support " "memory mapping.\n", dev_name); @@ -1365,7 +1534,7 @@ init_mmap_io (void) buf.memory = V4L2_MEMORY_MMAP; buf.index = n_buffers; - if (-1 == xioctl (fd, VIDIOC_QUERYBUF, &buf)) + if (-1 == xioctl (dev_fd, VIDIOC_QUERYBUF, &buf)) errno_exit ("VIDIOC_QUERYBUF"); buffers[n_buffers].length = buf.length; @@ -1374,7 +1543,7 @@ init_mmap_io (void) buf.length, PROT_READ | PROT_WRITE /* required */, MAP_SHARED /* recommended */, - fd, buf.m.offset); + dev_fd, buf.m.offset); if (MAP_FAILED == buffers[n_buffers].start) errno_exit ("mmap"); @@ -1427,7 +1596,7 @@ mainloop (void) fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; - if (-1 == xioctl (fd, VIDIOC_S_FMT, &fmt)) { + if (-1 == xioctl (dev_fd, VIDIOC_S_FMT, &fmt)) { if (EINVAL != errno) { errno_exit ("VIDIOC_S_FMT"); } @@ -1518,7 +1687,7 @@ init_device (void) struct v4l2_cropcap cropcap; struct v4l2_crop crop; - if (-1 == xioctl (fd, VIDIOC_QUERYCAP, &cap)) { + if (-1 == xioctl (dev_fd, VIDIOC_QUERYCAP, &cap)) { if (EINVAL == errno) { error_exit ("%s is not a V4L2 device.\n"); } else { @@ -1562,17 +1731,17 @@ init_device (void) cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - if (0 == xioctl (fd, VIDIOC_CROPCAP, &cropcap)) { + if (0 == xioctl (dev_fd, VIDIOC_CROPCAP, &cropcap)) { crop.type = cropcap.type; crop.c = cropcap.defrect; /* reset to default */ /* Errors ignored. */ - xioctl (fd, VIDIOC_S_CROP, &crop); + xioctl (dev_fd, VIDIOC_S_CROP, &crop); } else { /* Errors ignored. */ } - if (-1 == xioctl (fd, VIDIOC_G_STD, &std_id)) + if (-1 == xioctl (dev_fd, VIDIOC_G_STD, &std_id)) errno_exit ("VIDIOC_G_STD"); } @@ -1590,9 +1759,8 @@ open_device (void) error_exit ("%s is not a device file.\n", dev_name); } - fd = open (dev_name, O_RDWR /* required */ | O_NONBLOCK, 0); - - if (-1 == fd) { + dev_fd = open (dev_name, O_RDWR /* required */ | O_NONBLOCK, 0); + if (-1 == dev_fd) { error_exit ("Cannot open %s. %s.\n", dev_name, strerror (errno)); } @@ -1655,7 +1823,7 @@ do { \ for (i = 0; i < N_ELEMENTS (pf->mask); ++i) { pf_assert (pf->n_bits[i] + pf->shr[i] <= 32); pf_assert (pf->mask[i] - == (((1 << pf->n_bits[i]) - 1) + == (((1u << pf->n_bits[i]) - 1) << (32 - pf->n_bits[i] - pf->shr[i]))); } @@ -1732,12 +1900,12 @@ main (int argc, self_test (); for (;;) { - int index; + int opt_index; int c; c = getopt_long (argc, argv, short_options, long_options, - &index); + &opt_index); if (-1 == c) break; diff --git a/v4l2-apps/util/Makefile b/v4l2-apps/util/Makefile index cc0547c32..873553a95 100644 --- a/v4l2-apps/util/Makefile +++ b/v4l2-apps/util/Makefile @@ -1,9 +1,13 @@ # Makefile for linuxtv.org v4l2-apps/util +ifeq ($(KERNEL_DIR),) + KERNEL_DIR = /usr +endif + CPPFLAGS += -I../../linux/include -D_GNU_SOURCE LDFLAGS += -lm -binaries = v4l2-ctl v4l2-dbg ivtv-ctl cx18-ctl +binaries = v4l2-ctl v4l2-dbg ivtv-ctl cx18-ctl v4l-board-dbg ifeq ($(prefix),) prefix = /usr @@ -32,12 +36,12 @@ install: include ../Make.rules -parse.h: /usr/include/linux/input.h +parse.h: $(KERNEL_DIR)/include/linux/input.h @echo generating parse.h @echo -en "struct parse_key {\n\tchar *name;\n\tunsigned int value;\n} " >parse.h @echo -en "keynames[] = {\n" >>parse.h - @more /usr/include/linux/input.h |perl -n \ + @more $(KERNEL_DIR)/linux/input.h |perl -n \ -e 'if (m/^\#define\s+(KEY_[^\s]+)\s+(0x[\d\w]+|[\d]+)/) ' \ -e '{ printf "\t{\"%s\", %s},\n",$$1,$$2; }' \ -e 'if (m/^\#define\s+(BTN_[^\s]+)\s+(0x[\d\w]+|[\d]+)/) ' \ @@ -51,6 +55,8 @@ keytables: keytable: keytable.c parse.h keytables +v4l-board-dbg: v4l-board-dbg.c bttv-dbg.h saa7134-dbg.h em28xx-dbg.h + v4l2-driverids.cpp: ../../linux/include/linux/i2c-id.h @echo "struct driverid { const char *name; unsigned id; } driverids[] = {" >$@ @grep I2C_DRIVERID_ $^ | sed -e 's/.*I2C_DRIVERID_\([0-9A-Z_]*\)[^0-9]*\([0-9]*\).*/{ "\1", \2 },/' | tr A-Z a-z >>$@ @@ -60,3 +66,5 @@ v4l2-chipids.cpp: ../../linux/include/media/v4l2-chip-ident.h @echo "struct chipid { const char *name; unsigned id; } chipids[] = {" >$@ @grep V4L2_IDENT_ $^ | sed -e 's/.*V4L2_IDENT_\([0-9A-Z_]*\)[^=]*=[^0-9]*\([0-9]*\).*/{ "\1", \2 },/' | tr A-Z a-z >>$@ @echo "{ 0, 0 }};" >>$@ + + diff --git a/v4l2-apps/util/bttv-dbg.h b/v4l2-apps/util/bttv-dbg.h new file mode 100644 index 000000000..02f829773 --- /dev/null +++ b/v4l2-apps/util/bttv-dbg.h @@ -0,0 +1,97 @@ +/* + Copyright (C) 2008 Mauro Carvalho Chehab <mchehab@infradead.org> + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "v4l-board-dbg.h" + +#define BTTV_IDENT "bttv" + +/* Register name prefix */ +#define BTTV_PREFIX "BT848_" + +static struct board_regs bt8xx_regs_other[] = { + {0x000, BTTV_PREFIX "DSTATUS", 1}, + {0x054, BTTV_PREFIX "TEST", 1}, + {0x060, BTTV_PREFIX "ADELAY", 1}, + {0x064, BTTV_PREFIX "BDELAY", 1}, + {0x07C, BTTV_PREFIX "SRESET", 1}, + {0x100, BTTV_PREFIX "INT_STAT", 1}, + {0x110, BTTV_PREFIX "I2C", 1}, + {0x11C, BTTV_PREFIX "GPIO_REG_INP", 1}, + {0x120, BTTV_PREFIX "RISC_COUNT", 1}, + + /* This is also defined at bt8xx_regs with other name */ + {0x0fc, BTTV_PREFIX "VBI_PACK_DEL_VBI_HDELAY", 1}, +}; + +static struct board_regs bt8xx_regs[] = { + {0x004, BTTV_PREFIX "IFORM", 1}, + {0x008, BTTV_PREFIX "TDEC", 1}, + {0x00C, BTTV_PREFIX "E_CROP", 1}, + {0x08C, BTTV_PREFIX "O_CROP", 1}, + {0x010, BTTV_PREFIX "E_VDELAY_LO", 1}, + {0x090, BTTV_PREFIX "O_VDELAY_LO", 1}, + {0x014, BTTV_PREFIX "E_VACTIVE_LO", 1}, + {0x094, BTTV_PREFIX "O_VACTIVE_LO", 1}, + {0x018, BTTV_PREFIX "E_HDELAY_LO", 1}, + {0x098, BTTV_PREFIX "O_HDELAY_LO", 1}, + {0x01C, BTTV_PREFIX "E_HACTIVE_LO", 1}, + {0x09C, BTTV_PREFIX "O_HACTIVE_LO", 1}, + {0x020, BTTV_PREFIX "E_HSCALE_HI", 1}, + {0x0A0, BTTV_PREFIX "O_HSCALE_HI", 1}, + {0x024, BTTV_PREFIX "E_HSCALE_LO", 1}, + {0x0A4, BTTV_PREFIX "O_HSCALE_LO", 1}, + {0x028, BTTV_PREFIX "BRIGHT", 1}, + {0x02C, BTTV_PREFIX "E_CONTROL", 1}, + {0x0AC, BTTV_PREFIX "O_CONTROL", 1}, + {0x030, BTTV_PREFIX "CONTRAST_LO", 1}, + {0x034, BTTV_PREFIX "SAT_U_LO", 1}, + {0x038, BTTV_PREFIX "SAT_V_LO", 1}, + {0x03C, BTTV_PREFIX "HUE", 1}, + {0x040, BTTV_PREFIX "E_SCLOOP", 1}, + {0x0C0, BTTV_PREFIX "O_SCLOOP", 1}, + {0x048, BTTV_PREFIX "OFORM", 1}, + {0x04C, BTTV_PREFIX "E_VSCALE_HI", 1}, + {0x0CC, BTTV_PREFIX "O_VSCALE_HI", 1}, + {0x050, BTTV_PREFIX "E_VSCALE_LO", 1}, + {0x0D0, BTTV_PREFIX "O_VSCALE_LO", 1}, + {0x068, BTTV_PREFIX "ADC", 1}, + {0x044, BTTV_PREFIX "WC_UP", 1}, + {0x078, BTTV_PREFIX "WC_DOWN", 1}, + {0x06C, BTTV_PREFIX "E_VTC", 1}, + {0x080, BTTV_PREFIX "TGCTRL", 1}, + {0x0EC, BTTV_PREFIX "O_VTC", 1}, + {0x0D4, BTTV_PREFIX "COLOR_FMT", 1}, + {0x0B0, BTTV_PREFIX "VTOTAL_LO", 1}, + {0x0B4, BTTV_PREFIX "VTOTAL_HI", 1}, + {0x0D8, BTTV_PREFIX "COLOR_CTL", 1}, + {0x0DC, BTTV_PREFIX "CAP_CTL", 1}, + {0x0E0, BTTV_PREFIX "VBI_PACK_SIZE", 1}, + {0x0E4, BTTV_PREFIX "VBI_PACK_DEL", 1}, + {0x0E8, BTTV_PREFIX "FCNTR", 1}, + + {0x0F0, BTTV_PREFIX "PLL_F_LO", 1}, + {0x0F4, BTTV_PREFIX "PLL_F_HI", 1}, + {0x0F8, BTTV_PREFIX "PLL_XCI", 1}, + + {0x0FC, BTTV_PREFIX "DVSIF", 1}, + + {0x104, BTTV_PREFIX "INT_MASK", 4}, + {0x10C, BTTV_PREFIX "GPIO_DMA_CTL", 2}, + {0x114, BTTV_PREFIX "RISC_STRT_ADD", 4}, + {0x118, BTTV_PREFIX "GPIO_OUT_EN", 4}, + {0x11a, BTTV_PREFIX "GPIO_OUT_EN_HIBYTE", 4}, + {0x200, BTTV_PREFIX "GPIO_DATA", 4}, +}; diff --git a/v4l2-apps/util/em28xx-dbg.h b/v4l2-apps/util/em28xx-dbg.h new file mode 100644 index 000000000..d2edc60bc --- /dev/null +++ b/v4l2-apps/util/em28xx-dbg.h @@ -0,0 +1,84 @@ +/* + Copyright (C) 2008 Mauro Carvalho Chehab <mchehab@infradead.org> + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "v4l-board-dbg.h" + +#define EM28XX_IDENT "em28xx" + +/* Register name prefix */ +#define EM2800_PREFIX "EM2800_" +#define EM2880_PREFIX "EM2880_" +#define EM28XX_PREFIX "EM28XX_" + +static struct board_regs em28xx_regs[] = { + {0x08, EM2800_PREFIX "AUDIOSRC", 1}, + {0x04, EM2880_PREFIX "GPO", 1}, + {0x08, EM28XX_PREFIX "GPIO", 1}, + + {0x06, EM28XX_PREFIX "I2C_CLK", 1}, + {0x0a, EM28XX_PREFIX "CHIPID", 1}, + {0x0c, EM28XX_PREFIX "USBSUSP", 1}, + + {0x0e, EM28XX_PREFIX "AUDIOSRC", 1}, + {0x0f, EM28XX_PREFIX "XCLK", 1}, + + {0x10, EM28XX_PREFIX "VINMODE", 1}, + {0x11, EM28XX_PREFIX "VINCTRL", 1}, + {0x12, EM28XX_PREFIX "VINENABLE", 1}, + + {0x14, EM28XX_PREFIX "GAMMA", 1}, + {0x15, EM28XX_PREFIX "RGAIN", 1}, + {0x16, EM28XX_PREFIX "GGAIN", 1}, + {0x17, EM28XX_PREFIX "BGAIN", 1}, + {0x18, EM28XX_PREFIX "ROFFSET", 1}, + {0x19, EM28XX_PREFIX "GOFFSET", 1}, + {0x1a, EM28XX_PREFIX "BOFFSET", 1}, + + {0x1b, EM28XX_PREFIX "OFLOW", 1}, + {0x1c, EM28XX_PREFIX "HSTART", 1}, + {0x1d, EM28XX_PREFIX "VSTART", 1}, + {0x1e, EM28XX_PREFIX "CWIDTH", 1}, + {0x1f, EM28XX_PREFIX "CHEIGHT", 1}, + + {0x20, EM28XX_PREFIX "YGAIN", 1}, + {0x21, EM28XX_PREFIX "YOFFSET", 1}, + {0x22, EM28XX_PREFIX "UVGAIN", 1}, + {0x23, EM28XX_PREFIX "UOFFSET", 1}, + {0x24, EM28XX_PREFIX "VOFFSET", 1}, + {0x25, EM28XX_PREFIX "SHARPNESS", 1}, + + {0x26, EM28XX_PREFIX "COMPR", 1}, + {0x27, EM28XX_PREFIX "OUTFMT", 1}, + + {0x28, EM28XX_PREFIX "XMIN", 1}, + {0x29, EM28XX_PREFIX "XMAX", 1}, + {0x2a, EM28XX_PREFIX "YMIN", 1}, + {0x2b, EM28XX_PREFIX "YMAX", 1}, + + {0x30, EM28XX_PREFIX "HSCALELOW", 1}, + {0x31, EM28XX_PREFIX "HSCALEHIGH", 1}, + {0x32, EM28XX_PREFIX "VSCALELOW", 1}, + {0x33, EM28XX_PREFIX "VSCALEHIGH", 1}, + + {0x40, EM28XX_PREFIX "AC97LSB", 1}, + {0x41, EM28XX_PREFIX "AC97MSB", 1}, + {0x42, EM28XX_PREFIX "AC97ADDR", 1}, + {0x43, EM28XX_PREFIX "AC97BUSY", 1}, + + {0x02, EM28XX_PREFIX "MASTER_AC97", 1}, + {0x10, EM28XX_PREFIX "LINE_IN_AC97", 1}, + {0x14, EM28XX_PREFIX "VIDEO_AC97", 1}, +};
\ No newline at end of file diff --git a/v4l2-apps/util/saa7134-dbg.h b/v4l2-apps/util/saa7134-dbg.h new file mode 100644 index 000000000..aee29da76 --- /dev/null +++ b/v4l2-apps/util/saa7134-dbg.h @@ -0,0 +1,141 @@ +/* + Copyright (C) 2008 Mauro Carvalho Chehab <mchehab@infradead.org> + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "v4l-board-dbg.h" + +#define SAA7134_IDENT "saa7134" + +/* Register name prefix */ +#define SAA7134_PREFIX "SAA7134_" +#define SAA7135_PREFIX "SAA7135_" +#define SAA7133_PREFIX "SAA7133_" + +static struct board_regs saa7134_regs[] = { + {0x101, SAA7134_PREFIX "INCR_DELAY", 1}, + {0x102, SAA7134_PREFIX "ANALOG_IN_CTRL1", 1}, + {0x103, SAA7134_PREFIX "ANALOG_IN_CTRL2", 1}, + {0x104, SAA7134_PREFIX "ANALOG_IN_CTRL3", 1}, + {0x105, SAA7134_PREFIX "ANALOG_IN_CTRL4", 1}, + {0x106, SAA7134_PREFIX "HSYNC_START", 1}, + {0x107, SAA7134_PREFIX "HSYNC_STOP", 1}, + {0x108, SAA7134_PREFIX "SYNC_CTRL", 1}, + {0x109, SAA7134_PREFIX "LUMA_CTRL", 1}, + {0x10a, SAA7134_PREFIX "DEC_LUMA_BRIGHT", 1}, + {0x10b, SAA7134_PREFIX "DEC_LUMA_CONTRAST", 1}, + {0x10c, SAA7134_PREFIX "DEC_CHROMA_SATURATION", 1}, + {0x10d, SAA7134_PREFIX "DEC_CHROMA_HUE", 1}, + {0x10e, SAA7134_PREFIX "CHROMA_CTRL1", 1}, + {0x10f, SAA7134_PREFIX "CHROMA_GAIN", 1}, + {0x110, SAA7134_PREFIX "CHROMA_CTRL2", 1}, + {0x111, SAA7134_PREFIX "MODE_DELAY_CTRL", 1}, + {0x114, SAA7134_PREFIX "ANALOG_ADC", 1}, + {0x115, SAA7134_PREFIX "VGATE_START", 1}, + {0x116, SAA7134_PREFIX "VGATE_STOP", 1}, + {0x117, SAA7134_PREFIX "MISC_VGATE_MSB", 1}, + {0x118, SAA7134_PREFIX "RAW_DATA_GAIN", 1}, + {0x119, SAA7134_PREFIX "RAW_DATA_OFFSET", 1}, + {0x11e, SAA7134_PREFIX "STATUS_VIDEO1", 1}, + {0x11f, SAA7134_PREFIX "STATUS_VIDEO2", 1}, + {0x300, SAA7134_PREFIX "OFMT_VIDEO_A", 1}, + {0x301, SAA7134_PREFIX "OFMT_DATA_A", 1}, + {0x302, SAA7134_PREFIX "OFMT_VIDEO_B", 1}, + {0x303, SAA7134_PREFIX "OFMT_DATA_B", 1}, + {0x304, SAA7134_PREFIX "ALPHA_NOCLIP", 1}, + {0x305, SAA7134_PREFIX "ALPHA_CLIP", 1}, + {0x308, SAA7134_PREFIX "UV_PIXEL", 1}, + {0x309, SAA7134_PREFIX "CLIP_RED", 1}, + {0x30a, SAA7134_PREFIX "CLIP_GREEN", 1}, + {0x30b, SAA7134_PREFIX "CLIP_BLUE", 1}, + {0x180, SAA7134_PREFIX "I2C_ATTR_STATUS", 1}, + {0x181, SAA7134_PREFIX "I2C_DATA", 1}, + {0x182, SAA7134_PREFIX "I2C_CLOCK_SELECT", 1}, + {0x183, SAA7134_PREFIX "I2C_TIMER", 1}, + {0x140, SAA7134_PREFIX "NICAM_ADD_DATA1", 1}, + {0x141, SAA7134_PREFIX "NICAM_ADD_DATA2", 1}, + {0x142, SAA7134_PREFIX "NICAM_STATUS", 1}, + {0x143, SAA7134_PREFIX "AUDIO_STATUS", 1}, + {0x144, SAA7134_PREFIX "NICAM_ERROR_COUNT", 1}, + {0x145, SAA7134_PREFIX "IDENT_SIF", 1}, + {0x146, SAA7134_PREFIX "LEVEL_READOUT1", 1}, + {0x147, SAA7134_PREFIX "LEVEL_READOUT2", 1}, + {0x148, SAA7134_PREFIX "NICAM_ERROR_LOW", 1}, + {0x149, SAA7134_PREFIX "NICAM_ERROR_HIGH", 1}, + {0x14a, SAA7134_PREFIX "DCXO_IDENT_CTRL", 1}, + {0x14b, SAA7134_PREFIX "DEMODULATOR", 1}, + {0x14c, SAA7134_PREFIX "AGC_GAIN_SELECT", 1}, + {0x150, SAA7134_PREFIX "CARRIER1_FREQ0", 1}, + {0x151, SAA7134_PREFIX "CARRIER1_FREQ1", 1}, + {0x152, SAA7134_PREFIX "CARRIER1_FREQ2", 1}, + {0x154, SAA7134_PREFIX "CARRIER2_FREQ0", 1}, + {0x155, SAA7134_PREFIX "CARRIER2_FREQ1", 1}, + {0x156, SAA7134_PREFIX "CARRIER2_FREQ2", 1}, + {0x158, SAA7134_PREFIX "NUM_SAMPLES0", 1}, + {0x159, SAA7134_PREFIX "NUM_SAMPLES1", 1}, + {0x15a, SAA7134_PREFIX "NUM_SAMPLES2", 1}, + {0x15b, SAA7134_PREFIX "AUDIO_FORMAT_CTRL", 1}, + {0x160, SAA7134_PREFIX "MONITOR_SELECT", 1}, + {0x161, SAA7134_PREFIX "FM_DEEMPHASIS", 1}, + {0x162, SAA7134_PREFIX "FM_DEMATRIX", 1}, + {0x163, SAA7134_PREFIX "CHANNEL1_LEVEL", 1}, + {0x164, SAA7134_PREFIX "CHANNEL2_LEVEL", 1}, + {0x165, SAA7134_PREFIX "NICAM_CONFIG", 1}, + {0x166, SAA7134_PREFIX "NICAM_LEVEL_ADJUST", 1}, + {0x167, SAA7134_PREFIX "STEREO_DAC_OUTPUT_SELECT", 1}, + {0x168, SAA7134_PREFIX "I2S_OUTPUT_FORMAT", 1}, + {0x169, SAA7134_PREFIX "I2S_OUTPUT_SELECT", 1}, + {0x16a, SAA7134_PREFIX "I2S_OUTPUT_LEVEL", 1}, + {0x16b, SAA7134_PREFIX "DSP_OUTPUT_SELECT", 1}, + {0x16c, SAA7134_PREFIX "AUDIO_MUTE_CTRL", 1}, + {0x16d, SAA7134_PREFIX "SIF_SAMPLE_FREQ", 1}, + {0x16e, SAA7134_PREFIX "ANALOG_IO_SELECT", 1}, + {0x170, SAA7134_PREFIX "AUDIO_CLOCK0", 1}, + {0x171, SAA7134_PREFIX "AUDIO_CLOCK1", 1}, + {0x172, SAA7134_PREFIX "AUDIO_CLOCK2", 1}, + {0x173, SAA7134_PREFIX "AUDIO_PLL_CTRL", 1}, + {0x174, SAA7134_PREFIX "AUDIO_CLOCKS_PER_FIELD0", 1}, + {0x175, SAA7134_PREFIX "AUDIO_CLOCKS_PER_FIELD1", 1}, + {0x176, SAA7134_PREFIX "AUDIO_CLOCKS_PER_FIELD2", 1}, + {0x190, SAA7134_PREFIX "VIDEO_PORT_CTRL0", 1}, + {0x191, SAA7134_PREFIX "VIDEO_PORT_CTRL1", 1}, + {0x192, SAA7134_PREFIX "VIDEO_PORT_CTRL2", 1}, + {0x193, SAA7134_PREFIX "VIDEO_PORT_CTRL3", 1}, + {0x194, SAA7134_PREFIX "VIDEO_PORT_CTRL4", 1}, + {0x195, SAA7134_PREFIX "VIDEO_PORT_CTRL5", 1}, + {0x196, SAA7134_PREFIX "VIDEO_PORT_CTRL6", 1}, + {0x197, SAA7134_PREFIX "VIDEO_PORT_CTRL7", 1}, + {0x198, SAA7134_PREFIX "VIDEO_PORT_CTRL8", 1}, + {0x1a0, SAA7134_PREFIX "TS_PARALLEL", 1}, + {0x1a1, SAA7134_PREFIX "TS_PARALLEL_SERIAL", 1}, + {0x1a2, SAA7134_PREFIX "TS_SERIAL0", 1}, + {0x1a3, SAA7134_PREFIX "TS_SERIAL1", 1}, + {0x1a4, SAA7134_PREFIX "TS_DMA0", 1}, + {0x1a5, SAA7134_PREFIX "TS_DMA1", 1}, + {0x1a6, SAA7134_PREFIX "TS_DMA2", 1}, + {0x1B0, SAA7134_PREFIX "GPIO_GPMODE0", 1}, + {0x1B1, SAA7134_PREFIX "GPIO_GPMODE1", 1}, + {0x1B2, SAA7134_PREFIX "GPIO_GPMODE2", 1}, + {0x1B3, SAA7134_PREFIX "GPIO_GPMODE3", 1}, + {0x1B4, SAA7134_PREFIX "GPIO_GPSTATUS0", 1}, + {0x1B5, SAA7134_PREFIX "GPIO_GPSTATUS1", 1}, + {0x1B6, SAA7134_PREFIX "GPIO_GPSTATUS2", 1}, + {0x1B7, SAA7134_PREFIX "GPIO_GPSTATUS3", 1}, + {0x1c0, SAA7134_PREFIX "I2S_AUDIO_OUTPUT", 1}, + {0x1d0, SAA7134_PREFIX "SPECIAL_MODE", 1}, + {0x1d1, SAA7134_PREFIX "PRODUCTION_TEST_MODE", 1}, + {0x580, SAA7135_PREFIX "DSP_RWSTATE", 1}, + {0x586, SAA7135_PREFIX "DSP_RWCLEAR", 1}, + {0x591, SAA7133_PREFIX "I2S_AUDIO_CONTROL", 1}, +}; diff --git a/v4l2-apps/util/v4l-board-dbg.c b/v4l2-apps/util/v4l-board-dbg.c new file mode 100644 index 000000000..e74c7300e --- /dev/null +++ b/v4l2-apps/util/v4l-board-dbg.c @@ -0,0 +1,335 @@ +/* + Copyright (C) 2008 Mauro Carvalho Chehab <mchehab@infradead.org> + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <getopt.h> +#include <fcntl.h> +#include <errno.h> +#include <sys/ioctl.h> +#include <sys/time.h> +#include <linux/types.h> +#include <linux/videodev2.h> + +#include "bttv-dbg.h" +#include "saa7134-dbg.h" +#include "em28xx-dbg.h" + +#define ARRAY_SIZE(arr) ((int)(sizeof(arr) / sizeof((arr)[0]))) + +struct board_list { + char *name; + int prefix; /* Register prefix size */ + struct board_regs *regs; + int regs_size; + struct board_regs *alt_regs; + int alt_regs_size; +}; + +struct board_list boards[] = { + [0] = { /* From bttv-dbg.h */ + .name = BTTV_IDENT, + .prefix = sizeof(BTTV_PREFIX) - 1, + .regs = bt8xx_regs, + .regs_size = ARRAY_SIZE(bt8xx_regs), + .alt_regs = bt8xx_regs_other, + .alt_regs_size = ARRAY_SIZE(bt8xx_regs_other), + }, + [1] = { /* From saa7134-dbg.h */ + .name = SAA7134_IDENT, + .prefix = sizeof(SAA7134_PREFIX) - 1, + .regs = saa7134_regs, + .regs_size = ARRAY_SIZE(saa7134_regs), + .alt_regs = NULL, + .alt_regs_size = 0, + }, + [2] = { /* From em28xx-dbg.h */ + .name = EM28XX_IDENT, + .prefix = sizeof(EM28XX_PREFIX) - 1, + .regs = em28xx_regs, + .regs_size = ARRAY_SIZE(em28xx_regs), + .alt_regs = NULL, + .alt_regs_size = 0, + }, +}; + +static int is_get=0, is_set=0; + +static int doioctl(int fd, int request, void *parm, const char *name) +{ + int retVal; + + printf("ioctl %s ", name); + retVal = ioctl(fd, request, parm); + if (retVal < 0) + printf("failed: %s\n", strerror(errno)); + else + printf("ok\n"); + + return retVal; +} + +static void usage(void) +{ + printf("bttv-dbg <args>\n"); +} + +enum Option { + OptGetReg = 'g', + OptSetReg = 's', + OptHelp = 'h', +}; + +static void print_bin (int val, int size) +{ + int i, j, v; + + printf("("); + for (i = size-1; i >= 0; i--) { + v = (val >> (i * 8)) & 0xff; + for (j = 7; j >= 0; j--) { + int bit = (v >> j) & 0x1; + if (bit) + printf("1"); + else + printf("0"); + } + if (i) + printf(" "); + else + printf(")"); + } +} + +int main(int argc, char **argv) +{ + char *device = strdup("/dev/video0"); + char *reg_set = NULL; + int ch; + int i; + int fd = -1; + struct v4l2_register reg; + struct v4l2_capability cap; + struct board_list *curr_bd; + int board = 0; + struct option long_options[] = { + /* Please keep in alphabetical order of the short option. + That makes it easier to see which options are still free. */ + {"get-reg", no_argument, 0, OptGetReg}, + {"set-reg", required_argument, 0, OptSetReg}, + {"help", no_argument, 0, OptHelp}, + {0, 0, 0, 0} + }; + + /* command args */ + if (argc == 1) { + usage(); + return 0; + } + while (1) { + int option_index = 0; + + ch = getopt_long(argc, argv, "gs:", long_options, &option_index); + if (ch == -1) + break; + + switch (ch) { + case OptHelp: + usage(); + return 0; + case OptGetReg: + is_get++; + break; + case OptSetReg: + is_set++; + reg_set = optarg; + + break; + case '?': + fprintf(stderr, "Unknown argument `%s'\n", + argv[optind]); + usage(); + return 1; + } + } + if (optind < argc) { + printf("unknown arguments: "); + while (optind < argc) + printf("%s ", argv[optind++]); + printf("\n"); + usage(); + return 1; + } + + fd = open(device, O_RDWR); + if (fd < 0) { + fprintf(stderr, "Failed to open %s: %s\n", device, + strerror(errno)); + exit(1); + } + free(device); + + if (ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0) { + printf("Error while reading capabilities\n"); + exit(2); + } + + for (board = ARRAY_SIZE(boards)-1; board >= 0; board--) { + if (!strcasecmp((char *)cap.driver, boards[board].name)) + break; + } + if (board < 0) { + printf("This software doesn't support %s yet\n", cap.driver); + exit(3); + } + + curr_bd = &boards[board]; + + reg.match_type = V4L2_CHIP_MATCH_HOST; + reg.match_chip = 0; + + if (is_get) { + for (i = 0; i < curr_bd->regs_size; i++) { + char name[256]; + reg.reg = curr_bd->regs[i].reg; + if (ioctl(fd, VIDIOC_DBG_G_REGISTER, ®) < 0) { + printf("Error while reading. Maybe you're not root?\n"); + continue; + } + sprintf(name, "%s:", curr_bd->regs[i].name); + + switch (curr_bd->regs[i].size) { + case 1: + printf("%-32s %02llx ", name, reg.val & 0xff); + break; + case 2: + printf("%-32s %04llx ", name, reg.val & 0xffff); + break; + case 4: + printf("%-32s %08llx ", name, reg.val & 0xffffffff); + break; + } + print_bin (reg.val, curr_bd->regs[i].size); + printf("\n"); + } + return 0; + } + + if (is_set) { + char *reg_name; + int val; + int r, size; + unsigned prev; + struct board_regs *bd_reg; + + reg_name = strtok(reg_set, "=:"); + val = strtol(strtok(NULL, "=:"), 0L, 0); + + if (!reg_name) { + printf("set argument is invalid\n"); + return -1; + } + + for (i = curr_bd->regs_size - 1; i >=0 ; i--) { + if (!strcasecmp(reg_name, curr_bd->regs[i].name)) { + bd_reg = &curr_bd->regs[i]; + r = bd_reg->reg; + size = bd_reg->size; + break; + } + } + + if (i < 0) { + for (i = curr_bd->alt_regs_size - 1; i >=0 ; i--) { + if (!strcasecmp(reg_name, curr_bd->alt_regs[i].name)) { + bd_reg = &curr_bd->alt_regs[i]; + r = bd_reg->reg; + size = bd_reg->size; + break; + } + } + } + + if (i < 0) { + for (i = curr_bd->regs_size - 1; i >=0 ; i--) { + if (!strcasecmp(reg_name, curr_bd->regs[i].name + curr_bd->prefix)) { + bd_reg = &curr_bd->regs[i]; + r = bd_reg->reg; + size = bd_reg->size; + break; + } + } + } + + if (i < 0) { + for (i = curr_bd->alt_regs_size - 1; i >=0 ; i--) { + if (!strcasecmp(reg_name, curr_bd->alt_regs[i].name + curr_bd->prefix)) { + bd_reg = &curr_bd->regs[i]; + r = bd_reg->reg; + size = bd_reg->size; + break; + } + } + } + + if (i < 0) { + printf("Register not found\n"); + return -1; + } + + reg.reg = r; + if (ioctl(fd, VIDIOC_DBG_G_REGISTER, ®) < 0) { + printf("Error while reading register 0x%02x\n", r); + return -1; + } + prev = reg.val; + + switch (size) { + case 1: + reg.val = (reg.val & (~0xff)) | val; + break; + case 2: + reg.val = (reg.val & (~0xffff)) | val; + break; + case 4: + reg.val = val; + break; + } + + printf("Changing value of register %s(0x%x) from 0x%02x to 0x%02x\n", + bd_reg->name, r, prev, (unsigned int)reg.val); + + prev = reg.val; + + if (ioctl(fd, VIDIOC_DBG_S_REGISTER, ®) < 0) { + printf("Error while writing\n"); + return -1; + } + if (ioctl(fd, VIDIOC_DBG_G_REGISTER, ®) < 0) { + printf("Error while reading register 0x%02x\n", r); + return -1; + } + if (reg.val != prev) { + printf("Value of register %s(0x%x) is now 0x%02x\n", + bd_reg->name, r, (unsigned int)reg.val); + } + } + + close(fd); + exit(0); +} diff --git a/v4l2-apps/util/v4l-board-dbg.h b/v4l2-apps/util/v4l-board-dbg.h new file mode 100644 index 000000000..5d040812d --- /dev/null +++ b/v4l2-apps/util/v4l-board-dbg.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2008 Mauro Carvalho Chehab <mchehab@infradead.org> + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _V4L_BOARD_DBG +#define _V4L_BOARD_DBG +struct board_regs { + unsigned int reg; + char *name; + int size; +}; +#endif
\ No newline at end of file |